local lz_remind = require "lz_remind"
local util = require "util"

local table_insert = table.insert
local table_remove = table.remove
local table_sort = table.sort
local table_copy = table.copy

local assert = assert
local pairs = pairs
local ipairs = ipairs

local table_concat = table.concat
local string_format = string.format
local tostring = tostring

local function get_now_ustime()
    local time4,time5 = util.get_now_time() 
    return time4 * 1000000 + time5
end

local function draw_indent(indent)
    local s = {}
    for i = 1,indent do
        table_insert(s,'  ')
    end

    return table_concat(s,'')
end

local function _tostring_r(data,depth)
    if depth >= 6 then return '...' end
    if type(data) == 'table' then
        local s = {'{\n'}
        for k,v in pairs(data) do
            table_insert(s,string_format('%s%s:%s,\n',draw_indent(depth+1),tostring(k),_tostring_r(v,depth+1)))
        end
        table_insert(s,draw_indent(depth) .. '}\n')
        return table_concat(s,'')
    elseif type(data) == 'string' then
        return string_format('"%s"',tostring(data))
    else
        return tostring(data)
    end
end

local function tostring_r(data)
    return _tostring_r(data,0)
end

local CARD_SUIT_TYPE_INVALID = 0         --无效牌型
local CARD_SUIT_TYPE_WANGZHA = 1         --王炸
local CARD_SUIT_TYPE_ZHADAN = 2          --炸弹
local CARD_SUIT_TYPE_DANPAI = 3          --单牌
local CARD_SUIT_TYPE_DUIPAI = 4          --对牌
local CARD_SUIT_TYPE_SANZANGPAI = 5      --三张牌
local CARD_SUIT_TYPE_SANDAIYI = 6        --三带一
local CARD_SUIT_TYPE_DANSHUN = 7         --单顺
local CARD_SUIT_TYPE_SHUANGSHUN = 8      --双顺
local CARD_SUIT_TYPE_FEIJI = 9           --飞机
local CARD_SUIT_TYPE_FEIJIDAICIBANG = 10 --飞机带翅膀
local CARD_SUIT_TYPE_SIDAIER = 11        --四带二
local CARD_SUIT_TYPE_RUANZHA = 12        --软炸
local CARD_SUIT_TYPE_SANDAIYIDUI = 13    --三带一对
local CARD_SUIT_TYPE_SIDAILIANGDUI = 14  --四带两对


--[[
    每张卡牌分别由1-10,J,Q,K,black joker,red jocker 定义为1-15
--]]
local CARD_TWO_NUMBER = 2
local BLACK_JOKER_NUMBER = 14
local RED_JOKER_NUMBER = 15
local POWER_MAP = {
    [3] = 1,
    [4] = 2,
    [5] = 3,
    [6] = 4,
    [7] = 5,
    [8] = 6,
    [9] = 7,
    [10] = 8,
    [11] = 9, --J
    [12] = 10, --Q
    [13] = 11, --K
    [1] = 12,    --A

    [2] = 14,    --2

    [BLACK_JOKER_NUMBER] = 16,  --black joker
    [RED_JOKER_NUMBER] = 18,  --red joker
}
assert(#POWER_MAP == 15)
local CONTINUOUS_CARD_MAP = {}
for k,v in ipairs(POWER_MAP) do CONTINUOUS_CARD_MAP[v] = k end

local MARK_TYPE_WANGZHA = 1
local MARK_TYPE_ZHANDAN  = 2
local MARK_TYPE_DANPAI_RJOKER = 3
local MARK_TYPE_DANPAI_BJOKER = 4
local MARK_TYPE_DANPAI_TWO = 5

local MARK_TYPE_SCORE_MAP = {
    [MARK_TYPE_WANGZHA] = 8,--王炸8分
    [MARK_TYPE_ZHANDAN]  = 6,--炸弹6分
    [MARK_TYPE_DANPAI_RJOKER] = 4, --单牌大王4分
    [MARK_TYPE_DANPAI_BJOKER] = 3, --单牌小王3分
    [MARK_TYPE_DANPAI_TWO] = 2, --一张单牌二 2分
}

local REMAIN_CARD_COUNT_ONE = 1 --报单
local REMAIN_CARD_COUNT_TWO = 2 --报双

local self_card_id_list           --自己的手牌  分析过后的牌组
local shangjia_card_id_list         --上家的手牌  分析过后的牌组
local xiajia_card_id_list           --下家的手牌  分析过后的牌组

local self_card_type_list           --自己的手牌  分析过后的牌组
local shangjia_card_type_list         --上家的手牌  分析过后的牌组
local xiajia_card_type_list           --下家的手牌  分析过后的牌组
local self_card_handle_count           --自己的手牌数量
local shangjia_card_handle_count         --上家的手牌数量
local xiajia_card_handle_count           --下家的手牌数量
local xiajia_uid    --下家
local shangjia_uid  --上家

local make_card_type

--配置
local WEIGH_VALUE_CONF --权重配置
local ROB_DIZHU_CONF --抢地主配置
local JIABEI_CONF

WEIGH_VALUE_CONF = {
  [1] = {
    ["name"] = "王炸",
    ["base"] = 7,
    ["base_len"] = 1,
    ["add"] = 0,
  },
  [2] = {
    ["name"] = "炸弹",
    ["base"] = 7,
    ["base_len"] = 1,
    ["add"] = 0,
  },
  [3] = {
    ["name"] = "单牌",
    ["base"] = 1,
    ["base_len"] = 1,
    ["add"] = 0,
  },
  [4] = {
    ["name"] = "对牌",
    ["base"] = 2,
    ["base_len"] = 1,
    ["add"] = 0,
  },
  [5] = {
    ["name"] = "三条",
    ["base"] = 3,
    ["base_len"] = 1,
    ["add"] = 0,
  },
  [7] = {
    ["name"] = "单顺",
    ["base"] = 4,
    ["base_len"] = 5,
    ["add"] = 1,
  },
  [8] = {
    ["name"] = "双顺",
    ["base"] = 5,
    ["base_len"] = 3,
    ["add"] = 2,
  },
  [9] = {
    ["name"] = "飞机",
    ["base"] = 6,
    ["base_len"] = 2,
    ["add"] = 3,
  },
}

ROB_DIZHU_CONF = {
  [1] = {
    ["score"] = 0,
    ["probability"] = 0,
  },
  [2] = {
    ["score"] = 4,
    ["probability"] = 20,
  },
  [3] = {
    ["score"] = 6,
    ["probability"] = 50,
  },
  [4] = {
    ["score"] = 9,
    ["probability"] = 100,
  },
}

JIABEI_CONF = {
  [1] = {
    ["count"] = 3,
    ["probability"] = 100,
  },
  [2] = {
    ["count"] = 5,
    ["probability"] = 80,
  },
  [3] = {
    ["count"] = 7,
    ["probability"] = 10,
  },
  [4] = {
    ["count"] = 99,
    ["probability"] = 0,
  },
}

local san_zhang_priority_list 
local dan_shun_priority_list 
local shuang_shun_priority_list

local new_priority_list
-----------------------------------------common-----------------------------------------------
local function get_card_logic_value(card)
    dbglog(card)
    if type(card) ~= "number" then
        errlog(card)
    end
    return POWER_MAP[card % 100]
end

local function alloc_tmp_card_type_list()
    local  tmp_card_type_list = {
        [CARD_SUIT_TYPE_WANGZHA]    = {},
        [CARD_SUIT_TYPE_ZHADAN]     = {},
        [CARD_SUIT_TYPE_FEIJI]      = {},
        [CARD_SUIT_TYPE_SANZANGPAI] = {},
        [CARD_SUIT_TYPE_SHUANGSHUN] = {},
        [CARD_SUIT_TYPE_DANSHUN]    = {},
        [CARD_SUIT_TYPE_DUIPAI]     = {},
        [CARD_SUIT_TYPE_DANPAI]     = {},
   } 

   return tmp_card_type_list
end

local function extract_card_number(card_id)
    return card_id % 100
end

local function translate_to_count_number(card_suit)
    local card_number_set = {}
    for _,card_id in pairs(card_suit) do
        local number = extract_card_number(card_id)
        card_number_set[number] = (card_number_set[number] or 0) + 1
    end

    local count_number_map = {}
    for number,count in pairs(card_number_set) do
        local t = count_number_map[count]
        if not t then 
            t = {}
            count_number_map[count] = t
        end
        table_insert(t,number)
    end

    return count_number_map,card_number_set
end

local function process_card_id_list(card_id_list)
    local card_number_set = {}
    local real_card_number_set = {}
    for _,card_id in pairs(card_id_list) do
        local number = extract_card_number(card_id)
        card_number_set[number] = (card_number_set[number] or 0) + 1

        local t = real_card_number_set[number]
        if not t then t = {} real_card_number_set[number] = t end
        table_insert(t,card_id)
    end

    local card_count = 0
    local count_number_map = {}
    for number,count in pairs(card_number_set) do
        local t = count_number_map[count]
        if not t then 
            t = {}
            count_number_map[count] = t
        end
        table_insert(t,number)
        card_count = card_count + count
    end

    return card_number_set,real_card_number_set,count_number_map
end

local function full_result_cards(ret,real_card_number_set)
    local cards = {}
    for number,count in pairs(ret) do
        local card_id_list = assert(real_card_number_set[number])
        for i = 1,count do
            table_insert(cards,assert(card_id_list[i]))
        end
    end
    return cards
end

local function wipe_dai_pai_count(total_count,card_type_list)
    local dui_pai_count = #card_type_list[CARD_SUIT_TYPE_DUIPAI]
    local dan_pai_count = #card_type_list[CARD_SUIT_TYPE_DANPAI]
    for _,_ in pairs(card_type_list[CARD_SUIT_TYPE_ZHADAN]) do
        if dan_pai_count >= 2 then --四带两个单
            dan_pai_count = dan_pai_count - 2
            total_count = total_count - 2
            goto continue
        end
        if dui_pai_count >= 2 then --四带两个对
           dui_pai_count = dui_pai_count - 2
           total_count = total_count - 2
           goto continue
        end
        if dui_pai_count == 1 then --四带一对
            dui_pai_count = dui_pai_count - 1
            total_count = total_count - 1
            goto continue
        end

        ::continue::
    end

    local san_zhang_count = #card_type_list[CARD_SUIT_TYPE_SANZANGPAI]
    for _,feiji in pairs(card_type_list[CARD_SUIT_TYPE_FEIJI]) do
        san_zhang_count = san_zhang_count + #feiji
    end

    return total_count - math.min(san_zhang_count,dui_pai_count + dan_pai_count)
end

--得到手数
local function get_card_handle_count(total_card_type_list)
    local count = 0

    for _,card_type_list in pairs(total_card_type_list) do
        count = (count or 0) + #card_type_list
    end

    return wipe_dai_pai_count(count,total_card_type_list)
end

local function get_shun_zi_card_and_key(card_type,card_number)
    local card_count = 0
    if card_type == CARD_SUIT_TYPE_DANSHUN then
        card_count = 1
    elseif card_type == CARD_SUIT_TYPE_SHUANGSHUN then
        card_count = 2
    elseif card_type == CARD_SUIT_TYPE_FEIJI then
        card_count = 3
    else
        errlog("get shun_zi_count card type err!!!",card_type)
    end

    local ret = {}
    for _,number in pairs(card_number) do
        ret[number] = card_count
    end
    return ret,card_number[#card_number]
end

local function make_card_record(card_type,card_number)
    if card_type == CARD_SUIT_TYPE_DANPAI then
        return {[card_number] = 1},card_number
    elseif card_type == CARD_SUIT_TYPE_DUIPAI then
        return {[card_number] = 2},card_number
    elseif card_type == CARD_SUIT_TYPE_SANZANGPAI then
        return {[card_number] = 3},card_number
    elseif card_type == CARD_SUIT_TYPE_DANSHUN or 
           card_type == CARD_SUIT_TYPE_SHUANGSHUN or 
           card_type == CARD_SUIT_TYPE_FEIJI then
        return get_shun_zi_card_and_key(card_type,card_number)
    elseif card_type == CARD_SUIT_TYPE_ZHADAN then
        return {[card_number] = 4},card_number
    elseif card_type == CARD_SUIT_TYPE_WANGZHA then
        return {[BLACK_JOKER_NUMBER] = 1,[RED_JOKER_NUMBER] = 1},RED_JOKER_NUMBER
    else
        errlog("make_card_record card_type err",card_type)
    end
end

local function get_absolute_handle_count(uid,ddz_instance,total_card_type_list)
   local start_time = get_now_ustime()

   local dizhu_uid = ddz_instance:get_dizhu_uid()
   local compare_card1_ids = {}
   local compare_card2_ids = {}

   if uid == dizhu_uid then
        local farmer1_uid,famer2_uid = ddz_instance:get_farmer_uids()
        compare_card1_ids = ddz_instance:get_player_card_ids(farmer1_uid)
        compare_card2_ids = ddz_instance:get_player_card_ids(famer2_uid)
   else
        compare_card1_ids = ddz_instance:get_player_card_ids(dizhu_uid) 
   end

   local absolute_handle_count = 0
   local cards_id_list = ddz_instance:get_player_card_ids(uid)
   local _,real_card_number_set = process_card_id_list(cards_id_list)
   for card_type,card_type_list in pairs(total_card_type_list) do
       for _,card_number in pairs(card_type_list) do
           local ret,key = make_card_record(card_type,card_number)
           if ret then
              local card_suit = full_result_cards(ret,real_card_number_set)
              if not lz_remind.can_greater_than(compare_card1_ids,card_suit,card_type,key) and
                 not lz_remind.can_greater_than(compare_card2_ids,card_suit,card_type,key) then
                 absolute_handle_count = absolute_handle_count + 1
              end
           else
              errlog("make_card_record err",card_type)
           end
       end
   end

   --print("get_absolute_handle_count1231231231231231312",get_now_ustime() - start_time)
   return absolute_handle_count
end

local function player_can_must_win(uid,ddz_instance,card_type_list)
    local start_time = get_now_ustime()

    local handle_count = get_card_handle_count(card_type_list)
    local absolute_handle_count = get_absolute_handle_count(uid,ddz_instance,card_type_list)
    if absolute_handle_count >= handle_count - 1 then
        return true
    end

    --print("player_can_must_win10101010110101010===",get_now_ustime() - start_time)
    return false
end

local function rival_can_must_win(self)
   local dizhu_uid = self.ddz_instance:get_dizhu_uid()
   if self.uid == dizhu_uid then
        local farmer1_uid,famer2_uid = self.ddz_instance:get_farmer_uids()

        local farmer1_card_type_list = assert(make_card_type(farmer1_uid,self.ddz_instance)) 
        if player_can_must_win(farmer1_uid,self.ddz_instance,farmer1_card_type_list) then
            return true
        end

        local farmer2_card_type_list = assert(make_card_type(famer2_uid,self.ddz_instance)) 
        if player_can_must_win(famer2_uid,self.ddz_instance,farmer2_card_type_list) then
            return true
        end 
        return false
   else
        local dizhu_card_type_list = assert(make_card_type(dizhu_uid,self.ddz_instance)) 
        return player_can_must_win(dizhu_uid,self.ddz_instance,dizhu_card_type_list)
   end
end

--自己达到必赢条件
local function self_can_must_win(self)
    return player_can_must_win(self.uid,self.ddz_instance,self_card_type_list)
end

local function get_player_da_pai_count(ddz_instance,uid)
    local da_pai_count = 0
    local card_id_list = ddz_instance:get_player_card_ids(uid)
    local _,real_card_num_set = process_card_id_list(card_id_list)
    local pai_A = 12
    for number,cards in pairs(real_card_num_set) do
        if POWER_MAP[number] >= pai_A then
            da_pai_count = da_pai_count + #cards
        end
    end
    return da_pai_count
end

local function self_da_pai_more_than_rival(self)
    local self_da_pai_count = get_player_da_pai_count(self.ddz_instance,self.uid)
    local rival_da_pai_count = 0
    local dizhu_uid = self.ddz_instance:get_dizhu_uid()
    if self.uid == dizhu_uid then
        local farmer1_uid,farmer2_uid = self.ddz_instance:get_farmer_uids()
        local count1 = get_player_da_pai_count(self.ddz_instance,farmer1_uid)
        local count2 = get_player_da_pai_count(self.ddz_instance,farmer2_uid)
        rival_da_pai_count = count1 + count2
    else
        rival_da_pai_count = get_player_da_pai_count(self.ddz_instance,dizhu_uid)
    end

    return self_da_pai_count > rival_da_pai_count 
end

--得到权值
local function get_card_weigh_value(total_card_type_list)
    local weigh_value = 0
    for card_type,card_type_list in pairs(total_card_type_list) do
        for _,card_numbers in pairs(card_type_list) do
           if type(card_numbers) == 'table' then
                local beyond_len = #card_numbers - WEIGH_VALUE_CONF[card_type].base_len
                local add = beyond_len * WEIGH_VALUE_CONF[card_type].add
                weigh_value = weigh_value + WEIGH_VALUE_CONF[card_type].base + add
           else
                weigh_value = weigh_value + WEIGH_VALUE_CONF[card_type].base
           end
        end
    end

    return weigh_value
end

local function next_is_dizhu(self)
    local dizhu_uid = self.ddz_instance:get_dizhu_uid()
    local next_position_uid = self.ddz_instance:get_next_position_uid(self.uid)
    if next_position_uid == dizhu_uid then
        return true
    end
    return false
end

local function last_is_dizhu(self)
    local dizhu_uid = self.ddz_instance:get_dizhu_uid()
    local next_position_uid = self.ddz_instance:get_next_position_uid(self.uid)
    local last_position_uid = self.ddz_instance:get_next_position_uid(next_position_uid)
    if last_position_uid == dizhu_uid then
        return true
    end
    return false
end

--下家是否敌对
local function next_player_is_teammate(self)
    if self.uid == self.ddz_instance:get_dizhu_uid() then
        return false
    end
    if next_is_dizhu(self) then
        return false
    end
    return true
end

--上家是否敌对
local function last_player_is_teammate(self)
    if self.uid == self.ddz_instance:get_dizhu_uid() then
        return false
    end
    if last_is_dizhu(self) then
        return false
    end
    return true
end

local function rival_is_remain_one(self)
    local dizhu_uid = self.ddz_instance:get_dizhu_uid()
    local is_dizhu = dizhu_uid == self.uid
    local rival_min_count = self.ddz_instance:get_rival_min_card_count(is_dizhu)
    if rival_min_count == REMAIN_CARD_COUNT_ONE then
        return true
    end
    return false
end

local function rival_is_remain_two(self)
    local dizhu_uid = self.ddz_instance:get_dizhu_uid()
    local is_dizhu = dizhu_uid == self.uid
    local rival_min_count = self.ddz_instance:get_rival_min_card_count(is_dizhu)
    if rival_min_count == REMAIN_CARD_COUNT_TWO then
        return true
    end
    return false
end

local function player_is_teammate(self,uid)
    local dizhu_uid = self.ddz_instance:get_dizhu_uid()
    if self.uid == dizhu_uid and uid ~= dizhu_uid then
        return false
    end
    if self.uid ~= dizhu_uid and uid == dizhu_uid then
        return false
    end
    return true
end

local function can_seprate_dan_shun(self,dan_shun,number,last_uid)
    if player_is_teammate(self,uid) then
        return false
    end

    local max_num = dan_shun[#dan_shun]
    if max_num == number and #dan_shun >= 6 then
        return true
    end
    if POWER_MAP[max_num] - POWER_MAP[number] <= 1 and #dan_shun >= 7 then
        return true
    end
    local cards_id_list = self.ddz_instance:get_player_card_ids(last_uid)
    local card_type_list = assert(make_card_type(last_uid,self.ddz_instance))
    if get_card_handle_count(card_type_list) <= 1 then
        return true
    end

    return false
end

-----------------------------------------common-----------------------------------------------

-----------------------------------------check_rob_dizhu_begin--------------------------------------
local function get_wangzha_score(card_num_set)
    if card_num_set[BLACK_JOKER_NUMBER] and card_num_set[RED_JOKER_NUMBER] then
        return MARK_TYPE_SCORE_MAP[MARK_TYPE_WANGZHA]
    end
    return 0
end

local function get_zhadan_score(count_num_map)
   local zhadan_list = count_num_map[4] or {}
   return #zhadan_list * MARK_TYPE_SCORE_MAP[MARK_TYPE_ZHANDAN]
end

local function get_danpai_joker_score(card_num_set)
    if card_num_set[RED_JOKER_NUMBER] and not card_num_set[BLACK_JOKER_NUMBER] then
        return MARK_TYPE_SCORE_MAP[MARK_TYPE_DANPAI_RJOKER]
    end
    if card_num_set[BLACK_JOKER_NUMBER] and not card_num_set[RED_JOKER_NUMBER] then
        return MARK_TYPE_SCORE_MAP[MARK_TYPE_DANPAI_BJOKER]
    end
    return 0
end

local function get_danpai_two_score(real_card_number_set)
    local list_two = real_card_number_set[2] or {}
    if #list_two >= 4 then return 0 end
    return #list_two * MARK_TYPE_SCORE_MAP[MARK_TYPE_DANPAI_TWO]
end

local function get_cards_total_score(card_num_set,real_card_num_set,count_num_map)
    local total_score = 0
    total_score = total_score + get_wangzha_score(card_num_set)
    total_score = total_score + get_zhadan_score(count_num_map)
    total_score = total_score + get_danpai_joker_score(card_num_set)
    total_score = total_score + get_danpai_two_score(real_card_num_set)

    return total_score
end

local function get_probabilaty_by_score(self,total_score)
    local cur_probability = 0
    for _,tb in pairs(self.conf.rob_dizhu_conf) do
        if total_score >= tb.score then
            cur_probability = tb.probability
        end
    end
   
    return cur_probability
end

local function is_need_rob_dizhu(self)
    local cards_id_list = self.ddz_instance:get_player_card_ids(self.uid)
    local card_num_set,real_card_num_set,count_num_map = process_card_id_list(cards_id_list)
    local total_score = get_cards_total_score(card_num_set,real_card_num_set,count_num_map)
    local probability = get_probabilaty_by_score(self,total_score)

    if math.random(1, 100) <= probability then
        return true
    end
    return false
end

-----------------------------------------check_rob_dizhu_end--------------------------------------

-----------------------------------------check_jiabei_begin---------------------------------------
local function get_probabilaty_by_handle_count(handle_count)
    local cur_probability = 0
    for _,tb in pairs(JIABEI_CONF) do
        if handle_count <= tb.count then
            cur_probability = tb.probability
        end
    end
   
    return cur_probability
end

local function is_need_jiabei(uid,ddz_instance)
    local handle_count = get_card_handle_count(self_card_type_list)
    local probability  = get_probabilaty_by_handle_count(handle_count)
    if math.random(1, 100) <= probability then
        return true
    end
    return false
end

local function make_farmer_role(self)
    local dizhu_uid = self.ddz_instance:get_dizhu_uid()
    if self.uid == dizhu_uid then
        return
    end

    --满足必赢条件
    if self_can_must_win(self) then
        self.is_main_role = true
        return
    end
    local self_handle_count = get_card_handle_count(self_card_type_list)
    if self_handle_count <= 3 then
        self.is_main_role = true
        return
    end

    local another_framer_uid 
    local farmer1_uid,farmer2_uid = self.ddz_instance:get_farmer_uids()
    if self.uid == farmer1_uid then
        another_framer_uid = farmer2_uid
    else
        another_framer_uid = farmer1_uid
    end
    local another_card_type_list = assert(make_card_type(another_framer_uid,self.ddz_instance)) 

    local self_weigh_value = get_card_weigh_value(self_card_type_list)
    local another_weigh_value = get_card_weigh_value(another_card_type_list)
    if self_weigh_value >= another_weigh_value then
        self.is_main_role = true
        return
    end
    local another_handle_count = get_card_handle_count(another_card_type_list)
    if self_handle_count < another_handle_count then
        self.is_main_role = true
        return
    end

    self.is_main_role = false
end
-----------------------------------------check_jiabei_end-----------------------------------------

-----------------------------------------make_card_type_begin-------------------------------------
local function make_wangzha(real_card_num_set,card_type_list)
    if real_card_num_set[BLACK_JOKER_NUMBER] and real_card_num_set[RED_JOKER_NUMBER] then
        table_insert(card_type_list[CARD_SUIT_TYPE_WANGZHA],{real_card_num_set[BLACK_JOKER_NUMBER][1],real_card_num_set[RED_JOKER_NUMBER][1]})
        real_card_num_set[BLACK_JOKER_NUMBER] = nil
        real_card_num_set[RED_JOKER_NUMBER]   = nil
    end
end

--排除顺子 头尾三张
local function check_begin_end(dan_shun,double_shun_list,real_card_number_set)
    if #real_card_number_set[dan_shun[1]] >= 3 then
        for _,v in pairs(double_shun_list) do
            if v[1] == dan_shun[1] then
                table_remove(v,1)
                break
            end
        end
        table_remove(dan_shun,1)
    end

    if #real_card_number_set[dan_shun[#dan_shun]] >= 3 then
        for _,v in pairs(double_shun_list) do
            if v[#v] == dan_shun[#dan_shun] then
                table_remove(v,#v)
                break
            end
        end
        table_remove(dan_shun,#dan_shun)
    end
end

--寻找权重最高的顺子
local function check_line_wight(line,real_card_number_set,double_shun_list)
    local ret_line = {}
    local max_weight = 0
    for i = 5,#line do
        local line_tem = {}
        local weight = i
        for j = 1 , i do
            local number = line[j]
            table_insert(line_tem,number)
            if #real_card_number_set[number] == 2 then
                weight = weight - 2
            elseif #real_card_number_set[number] == 3 then
                weight = weight - 3
            end  
            for _,v in pairs(double_shun_list) do
                if v == number then
                    weight = weight + 2
                    break
                end
            end
        end
        if weight > max_weight then
            max_weight = weight
            ret_line = line_tem
        end
    end

    for i = 5,#line do
        local line_tem = {}
        local weight = i
        for j = 1 , i do
            local number = line[#line - i + j]
            table_insert(line_tem,number)
            if #real_card_number_set[number] == 2 then
                weight = weight - 2
            elseif #real_card_number_set[number] == 3 then
                weight = weight - 3
            end  
            for _,v in pairs(double_shun_list) do
                if v == number then
                    weight = weight + 2
                    break
                end
            end
        end
        if weight > max_weight then
            max_weight = weight
            ret_line = line_tem
        end
    end

    return ret_line,max_weight
end

--分析顺子
local function analyse_shunzi(dan_shun,double_shun_list,real_card_number_set,card_type_list)
    dbglog(dan_shun,real_card_number_set)
    --排除顺子 头尾三张
    -- check_begin_end(dan_shun,double_shun_list,real_card_number_set)
    -- if #dan_shun < 5 then return end

    --取最佳重合双顺
    local max_count = 0    --取重合最长的
    local value = {}
    for _,v in pairs(double_shun_list) do
        --顺子中 双顺 最小值小于 顺子最大值-5 并且 双顺最大值 大于顺子最小值 + 5
        dbglog(v,dan_shun)
        if POWER_MAP[v[1]] <= POWER_MAP[dan_shun[#dan_shun - 4]] and POWER_MAP[v[#v]] >= POWER_MAP[dan_shun[5]] then
            local count = #v 

            if count >= max_count then 
                max_count = count
                value = v
            end
        end
    end  

    card_type_list[CARD_SUIT_TYPE_DANSHUN] = card_type_list[CARD_SUIT_TYPE_DANSHUN] or {}

    if max_count > 0 and max_count < #dan_shun - 1 then

        local line_1 = {}
        local line_2 = {}
        for number = value[1] , dan_shun[#dan_shun] do
            table_insert(line_1, number)
        end
        line_1 = check_line_wight(line_1,real_card_number_set,double_shun_list)
        local card_list1 = {}
        for _,number in ipairs(line_1) do
            local card = table_remove(real_card_number_set[number],1)
            table_insert(card_list1,card)
        end

        for number = dan_shun[1] , value[#value] do
            table_insert(line_2, number)
        end
        line_2 = check_line_wight(line_2,real_card_number_set,double_shun_list)
        local card_list2 = {}
        for _,number in ipairs(line_2) do
            local card = table_remove(real_card_number_set[number],1)
            table_insert(card_list2,card)
        end
        if #card_list1 >= 5 then
            table_insert(card_type_list[CARD_SUIT_TYPE_DANSHUN],card_list1)
        end
        if #card_list2 >= 5 then
            table_insert(card_type_list[CARD_SUIT_TYPE_DANSHUN],card_list2
)        end
    else  
        --没有拆分牌 根据权重判断顺子是否合适。 权重等于 顺子数量 减去 对子2  三张 3 权重大于0 才组合顺子
        local line,weight = check_line_wight(dan_shun,real_card_number_set,double_shun_list)
        if weight > 0 then
            local card_list = {}
            for _,number in pairs(line) do
                local card = table_remove(real_card_number_set[number],1)
                table_insert(card_list,card)
            end
            if #card_list >= 5 then 
                table_insert(card_type_list[CARD_SUIT_TYPE_DANSHUN],card_list)
            end
        end
    end
end

local function make_sunzi_new(real_card_number_set,card_type_list)
    local start_time = get_now_ustime()
    local real_card_number_set_copy = table_copy(real_card_number_set)
    local three_shun = {}
    local three_shun_list = {}
    local three_shun_count = 0
    local power = 1
    --优先排除飞机三连 拆分好顺子后再组合飞机牌
    while true do
        local number = CONTINUOUS_CARD_MAP[power]
        if not number then
            break 
        end

        if real_card_number_set_copy[number] and #real_card_number_set_copy[number] >= 3 then
            table_insert(three_shun,number)
            three_shun_count = three_shun_count + 1 
        elseif three_shun_count < 2 then
            three_shun = {}
            three_shun_count = 0
        end
        power = power + 1

        if three_shun_count >= 2 then
            table_insert(three_shun_list,three_shun)

            for _,number in pairs(three_shun) do
                table_remove(real_card_number_set_copy[number],1)
                if #real_card_number_set_copy[number] <= 0 then
                    real_card_number_set_copy[number] = nil
                end
            end
            three_shun = {}
            three_shun_count = 0
        end
    end


    local tmp_dan_shun_list = {}
    local dan_shun = {}
    local double_shun_list = {}
    local double_shun = {}

    local dan_shun_count = 0
    power = 1
    --选取顺子
    while true do
        local number = CONTINUOUS_CARD_MAP[power]
        if not number then
            if dan_shun_count >= 5 then
               --分析顺子牌 去除头尾三张 和 拆分两个顺子
               analyse_shunzi(dan_shun,double_shun_list,real_card_number_set,card_type_list)
               double_shun_list = {}
               double_shun = {}
               dan_shun = {}
               dan_shun_count = 0
            end
            break 
        end

        if real_card_number_set_copy[number] then
            table_insert(dan_shun,number)
            if #real_card_number_set_copy[number] > 1 then
                table_insert(double_shun,number)
            else
                if #double_shun > 1 then
                    table_insert(double_shun_list,double_shun)
                end
                double_shun = {}
            end
            dan_shun_count = dan_shun_count + 1 
        elseif dan_shun_count < 5 then
            double_shun_list = {}
            double_shun = {}
            dan_shun = {}
            dan_shun_count = 0
        else
            if #double_shun > 1 then
                table_insert(double_shun_list,double_shun)
                double_shun = {}
            end

            if dan_shun_count >= 5 then
               --分析顺子牌 去除头尾三张 和 拆分两个顺子
               analyse_shunzi(dan_shun,double_shun_list,real_card_number_set,card_type_list)
               double_shun_list = {}
               double_shun = {}
               dan_shun = {}
               dan_shun_count = 0
            end
        end
        power = power + 1
    end
end

local function make_dan_shun(real_card_number_set,card_type_list)
    local start_time = get_now_ustime()

    local tmp_dan_shun_list = {}
    local dan_shun = {}
    local dan_shun_count = 0
    local power = 1
    dbglog("real_card_number_set:",real_card_number_set)
    --选取最小五连
    while true do
        local number = CONTINUOUS_CARD_MAP[power]
        if not number then
            break 
        end

        if real_card_number_set[number] then
            table_insert(dan_shun,number)
            dbglog("dan_shun:",dan_shun)
            dan_shun_count = dan_shun_count + 1 
        elseif dan_shun_count < 5 then
            dan_shun = {}
            dan_shun_count = 0
        end
        power = power + 1

        if dan_shun_count >= 5 then
            table_insert(tmp_dan_shun_list,dan_shun)

            for _,number in pairs(dan_shun) do
                table_remove(real_card_number_set[number],1)
                if #real_card_number_set[number] <= 0 then
                    real_card_number_set[number] = nil
                end
            end
            dan_shun = {}
            dan_shun_count = 0
            power = 1
        end
    end
    --拓展五连
    for number,_ in pairs(real_card_number_set) do
        local power = POWER_MAP[number]
        for _,dan_shun in pairs(tmp_dan_shun_list) do
            local max_num = dan_shun[#dan_shun]
            local last_power = POWER_MAP[max_num]
            if last_power + 1 == power then
                table_insert(dan_shun,number)
                table_remove(real_card_number_set[number],1)
                if #real_card_number_set[number] <= 0 then
                    real_card_number_set[number] = nil
                end
                break
            end
        end
    end
    --合并顺子
    local index = 1
    for i=1,#tmp_dan_shun_list do
        local pre_list = tmp_dan_shun_list[i]
        local j = i+1
        while tmp_dan_shun_list[j] do
            local next_list = tmp_dan_shun_list[j]
            local pre_number = pre_list[#pre_list]
            local pre_power = POWER_MAP[pre_number]
            local next_number = next_list[1]
            local next_power = POWER_MAP[next_number]
            if pre_power + 1 == next_power then
                for _,number in pairs(next_list) do
                    table_insert(tmp_dan_shun_list[i],number)
                end
                table_remove(tmp_dan_shun_list,j)
            else
                j = j + 1
            end
        end
    end

    if next(tmp_dan_shun_list) then
        card_type_list[CARD_SUIT_TYPE_DANSHUN] = tmp_dan_shun_list
    end

    --print("make_dan_shun2222222",get_now_ustime() - start_time)
end

local function make_zhadan(real_card_num_set,card_type_list)
    local start_time = get_now_ustime()

    for number,cards_id_list in pairs(real_card_num_set) do
        if #cards_id_list == 4 then
            table_insert(card_type_list[CARD_SUIT_TYPE_ZHADAN],cards_id_list)
            real_card_num_set[number] = nil
        end
    end
    table_sort(card_type_list[CARD_SUIT_TYPE_ZHADAN],function(a,b) return (get_card_logic_value(a[1]) < get_card_logic_value(b[1])) end)
    --print("make_zhadan66666666666",get_now_ustime() - start_time)
end

local function make_dan_pai(real_card_num_set,card_type_list)
    local start_time = get_now_ustime()
    local danpai_num = {}
    for number,card_id_list in pairs(real_card_num_set) do
       if #card_id_list == 1 then
            table_insert(danpai_num,number)
       end
   end

   for _,number in pairs(danpai_num) do
        local card = table_remove(real_card_num_set[number],1)
        table_insert(card_type_list[CARD_SUIT_TYPE_DANPAI],{card})
   end

   local tmp_list = card_type_list[CARD_SUIT_TYPE_DANPAI]
   table_sort(tmp_list,function(a,b) return (get_card_logic_value(a[1]) < get_card_logic_value(b[1])) end)

   --print("make_dan_pai888888888888",get_now_ustime() - start_time)
end

local function make_dui_pai(real_card_num_set,card_type_list)
   local start_time = get_now_ustime()
   local dui_pai_num = {}
   for number,card_id_list in pairs(real_card_num_set) do
       if #card_id_list == 2 then
            table_insert(dui_pai_num,number)
       end
   end

   for _,number in pairs(dui_pai_num) do
            local card_list = {}
            for i = 1 , 2 do
                local card = table_remove(real_card_num_set[number],1)
                table_insert(card_list,card)
            end
            table_insert(card_type_list[CARD_SUIT_TYPE_DUIPAI],card_list)
   end

   local tmp_list = card_type_list[CARD_SUIT_TYPE_DUIPAI]
   table_sort(tmp_list,function(a,b) return (get_card_logic_value(a[1]) < get_card_logic_value(b[1])) end)

   --print("make_dui_pai77777777777777",get_now_ustime() - start_time)
end

local function make_san_zhang_pai(real_card_num_set,card_type_list)
    local start_time = get_now_ustime()
    local san_zhang_list = {}
    local single_list = {}
    local double_list = {}
    local wang_er_dan = {}
    local er_duizi = {}
    local card_count = 0
    for number,card_id_list in pairs(real_card_num_set) do
        card_count = card_count + #card_id_list
        if #card_id_list == 3 then
            table_insert(san_zhang_list,number)
        elseif #card_id_list == 2 then 
            if POWER_MAP[number] < POWER_MAP[CARD_TWO_NUMBER] then
                table_insert(double_list,number)
            else
                table_insert(er_duizi,number)
            end
        elseif #card_id_list == 1 then
            if POWER_MAP[number] < POWER_MAP[CARD_TWO_NUMBER] then
                table_insert(single_list,number)
            else
                table_insert(wang_er_dan,number)
            end
            -- table_insert(card_type_list[CARD_SUIT_TYPE_SANZANGPAI],number)
            -- real_card_num_set[number] = nil
        end
    end
    table_sort(san_zhang_list,function(a,b) return (POWER_MAP[a] < POWER_MAP[b]) end)
    table_sort(single_list,function(a,b) return (POWER_MAP[a] < POWER_MAP[b]) end)
    table_sort(double_list,function(a,b) return (POWER_MAP[a] < POWER_MAP[b]) end)

    for _,number in pairs(san_zhang_list) do
        local card_list = {}
        for i = 1 , 3 do
            local card = table_remove(real_card_num_set[number],1)
            table_insert(card_list,card)
        end
        if #single_list > 0 then
            local single_number = table_remove(single_list,1)
            local card = table_remove(real_card_num_set[single_number],1)
            table_insert(card_list,card) 
            table_insert(card_type_list[CARD_SUIT_TYPE_SANDAIYI],card_list)          
        elseif #double_list > 0 then
            local double_number = table_remove(double_list,1)
            local card = table_remove(real_card_num_set[double_number],1)
            table_insert(card_list,card)
            card = table_remove(real_card_num_set[double_number],1)
            table_insert(card_list,card)    
            table_insert(card_type_list[CARD_SUIT_TYPE_SANDAIYIDUI],card_list)      
        elseif #er_duizi > 0 and card_count <= 5 then
            local double_number = table_remove(er_duizi,1)
            local card = table_remove(real_card_num_set[double_number],1)
            table_insert(card_list,card)
            card = table_remove(real_card_num_set[double_number],1)
            table_insert(card_list,card)    
            table_insert(card_type_list[CARD_SUIT_TYPE_SANDAIYIDUI],card_list) 
        elseif #wang_er_dan > 0 and card_count <= 4 then
            local single_number = table_remove(wang_er_dan,1)
            local card = table_remove(real_card_num_set[single_number],1)
            table_insert(card_list,card) 
            table_insert(card_type_list[CARD_SUIT_TYPE_SANDAIYI],card_list)    
        else
            table_insert(card_type_list[CARD_SUIT_TYPE_SANZANGPAI],card_list)
        end
    end

    if card_type_list[CARD_SUIT_TYPE_SANZANGPAI] and #card_type_list[CARD_SUIT_TYPE_SANZANGPAI] > 1 then
       table_sort(card_type_list[CARD_SUIT_TYPE_SANZANGPAI],function(a,b) return (get_card_logic_value(a[1]) < get_card_logic_value(b[1])) end)
    end

    if card_type_list[CARD_SUIT_TYPE_SANDAIYIDUI] and #card_type_list[CARD_SUIT_TYPE_SANDAIYIDUI] > 1 then
       table_sort(card_type_list[CARD_SUIT_TYPE_SANDAIYIDUI],function(a,b) return (get_card_logic_value(a[1]) < get_card_logic_value(b[1])) end)
    end

    if card_type_list[CARD_SUIT_TYPE_SANDAIYI] and #card_type_list[CARD_SUIT_TYPE_SANDAIYI] > 1 then
       table_sort(card_type_list[CARD_SUIT_TYPE_SANDAIYI],function(a,b) return (get_card_logic_value(a[1]) < get_card_logic_value(b[1])) end)
    end

    --print("make_san_zhang_pai+++++",get_now_ustime() - start_time)
end

local function make_feiji(real_card_number_set,card_type_list)
    local start_time = get_now_ustime()

    local tmp_list = {}
    local danpai_list = {}
    local duizi_list = {} 
    local wang_er_dan = {}
    local er_duizi = {}
    for number,cards_id_list in pairs(real_card_number_set) do
        if #cards_id_list == 3 then
            table_insert(tmp_list,number)
        end
        --排除2
        if #cards_id_list == 2 then
            if POWER_MAP[number] < POWER_MAP[CARD_TWO_NUMBER] then
                table_insert(duizi_list,number)
            else
                table_insert(er_duizi,number)
            end
        end
        --排除 大小王和 2
        if #cards_id_list == 1 then
            if POWER_MAP[number] < POWER_MAP[CARD_TWO_NUMBER] then
                table_insert(danpai_list,number)
            else
                table_insert(wang_er_dan,number)
            end     
        end
    end

    if #tmp_list < 2 then return end
         
    local power_list = {}
    for _,number in pairs(tmp_list) do
        table_insert(power_list,POWER_MAP[number])
    end

    table_sort(power_list)
    table_sort(danpai_list,function(a,b) return (POWER_MAP[a] < POWER_MAP[b]) end)
    table_sort(duizi_list,function(a,b) return (POWER_MAP[a] < POWER_MAP[b]) end)

    local last_power = power_list[1]
    local continuous = {CONTINUOUS_CARD_MAP[last_power]}
    local continuous_list = {}
    for i = 2,#power_list do
        local power = power_list[i]
        if power == last_power + 1 then
            last_power = power
            table_insert(continuous,CONTINUOUS_CARD_MAP[power])

            goto continue
        end
        if #continuous >= 2 then
            table_insert(continuous_list,continuous)
        end
        if #continuous > 0 then
            continuous = {}
        end
        last_power = power
        table_insert(continuous,CONTINUOUS_CARD_MAP[power])

        ::continue::
    end
    if #continuous >= 2 then
        table_insert(continuous_list,continuous)
    end
    for _,value in pairs(continuous_list) do
        --一手牌
        local card_handler_list = {}
        for _,number in pairs(value) do
            for _,card in pairs(real_card_number_set[number]) do
                table_insert(card_handler_list,card)
            end
            real_card_number_set[number] = nil
        end

        if #danpai_list >= #value then
            for i,_ in pairs(value) do
                local card = table_remove(real_card_number_set[danpai_list[i]],1)
                table_insert(card_handler_list,card)
            end
            dbglog(danpai_list,real_card_number_set,value,card_handler_list)
            table_insert(card_type_list[CARD_SUIT_TYPE_FEIJIDAICIBANG],card_handler_list)
        elseif #duizi_list >= #value then
            for i,_ in pairs(value) do
                local card = table_remove(real_card_number_set[duizi_list[i]],1)
                table_insert(card_handler_list,card)
                card = table_remove(real_card_number_set[duizi_list[i]],1)
                table_insert(card_handler_list,card)
            end
            dbglog(danpai_list,real_card_number_set,value,card_handler_list)
            table_insert(card_type_list[CARD_SUIT_TYPE_FEIJIDAICIBANG],card_handler_list)
        elseif #danpai_list + (#duizi_list)*2 + #wang_er_dan + (#er_duizi)*2 >= #value then
            local count = #value
            for _,number in ipairs(danpai_list) do
                local card = table_remove(real_card_number_set[number],1)
                table_insert(card_handler_list,card)
                count = count - 1
                if count == 0 then
                    dbglog(danpai_list,real_card_number_set,value,card_handler_list)
                    table_insert(card_type_list[CARD_SUIT_TYPE_FEIJIDAICIBANG],card_handler_list)
                    goto continue
                end
            end

            for _,number in ipairs(duizi_list) do
                local card = table_remove(real_card_number_set[number],1)
                table_insert(card_handler_list,card)
                count = count - 1
                if count == 0 then
                    dbglog(danpai_list,real_card_number_set,value,card_handler_list)
                    table_insert(card_type_list[CARD_SUIT_TYPE_FEIJIDAICIBANG],card_handler_list)
                    goto continue
                end

                card = table_remove(real_card_number_set[number],1)
                table_insert(card_handler_list,card)
                count = count - 1
                if count == 0 then
                    dbglog(danpai_list,real_card_number_set,value,card_handler_list)
                    table_insert(card_type_list[CARD_SUIT_TYPE_FEIJIDAICIBANG],card_handler_list)
                    goto continue
                end
            end

            for _,number in ipairs(wang_er_dan) do
                local card = table_remove(real_card_number_set[number],1)
                table_insert(card_handler_list,card)
                count = count - 1
                if count == 0 then
                    dbglog(danpai_list,real_card_number_set,value,card_handler_list)
                    table_insert(card_type_list[CARD_SUIT_TYPE_FEIJIDAICIBANG],card_handler_list)
                    goto continue
                end
            end

            for _,number in ipairs(er_duizi) do
                local card = table_remove(real_card_number_set[number],1)
                table_insert(card_handler_list,card)
                count = count - 1
                if count == 0 then
                    dbglog(danpai_list,real_card_number_set,value,card_handler_list)
                    table_insert(card_type_list[CARD_SUIT_TYPE_FEIJIDAICIBANG],card_handler_list)
                    goto continue
                end

                card = table_remove(real_card_number_set[number],1)
                table_insert(card_handler_list,card)
                count = count - 1
                if count == 0 then
                    dbglog(danpai_list,real_card_number_set,value,card_handler_list)
                    table_insert(card_type_list[CARD_SUIT_TYPE_FEIJIDAICIBANG],card_handler_list)
                    goto continue
                end
            end
            ::continue::
        else
            dbglog(card_handler_list)
            table_insert(card_type_list[CARD_SUIT_TYPE_FEIJI],card_handler_list)
        end
    end

    --print("make_feiji44444",get_now_ustime() - start_time)
end

local function is_equal_dan_shun(dan_shun1,dan_shun2)
    if #dan_shun1 ~= #dan_shun2 then
        return false
    end

    local tmp_map = {}
    for _,number in pairs(dan_shun2) do
        tmp_map[number] = true
    end
    for _,num in pairs(dan_shun1) do
        if not tmp_map[num] then
            return false
        end
    end

    return true
end

--检测双顺权重 返回双顺最优解
local function check_shuang_shun_wight(real_card_number_set,tmp_list)
    local ret_list = {}
    local max_wight = 0
    for i = 3 , #tmp_list do
        local wight = i * 2
        local number_list = {}
        for j = 1 ,i do
            if real_card_number_set[tmp_list[j]] and #real_card_number_set[tmp_list[j]] == 3 then
                -- if POWER_MAP[tmp_list[j]] > 11 then
                --     wight = wight - 5
                -- else 
                    wight = wight - 3
                -- end
            end
            table_insert(number_list,tmp_list[j])
        end
        if wight > max_wight then
            max_wight = wight
            ret_list = number_list
        end
    end

    for i = 3 , #tmp_list do
        local wight = i * 2
        local number_list = {}
        for j = 1 ,i do
            if real_card_number_set[tmp_list[#tmp_list - i + j]] and #real_card_number_set[tmp_list[#tmp_list - i + j]] == 3 then
                -- if POWER_MAP[tmp_list[j]] > 11 then
                --     wight = wight - 5
                -- else 
                    wight = wight - 3
                -- end
            end
            table_insert(number_list,tmp_list[j])
        end
        if wight > max_wight then
            max_wight = wight
            ret_list = number_list
        end
    end

    return ret_list
end

local function make_shuang_shun(real_card_number_set,card_type_list)
    local start_time = get_now_ustime()

    --在单顺中组建双顺
    local type_list = card_type_list[CARD_SUIT_TYPE_DANSHUN]

    local i = 1
    while type_list[i] and type_list[i+1] do
        if is_equal_dan_shun(type_list[i],type_list[i+1]) then
            table_insert(card_type_list[CARD_SUIT_TYPE_SHUANGSHUN],type_list[i])
            for j=1,2 do
                table_remove(type_list,i)
            end
        else
            i = i + 1
        end
    end
    --在剩余牌中组建双顺
    local power = 1
    local tmp_list = {}
    local tmp_count = 0
    while true do
        local number = CONTINUOUS_CARD_MAP[power]
        if not number then
            break 
        end
        local card_id_list = real_card_number_set[number]
        if card_id_list and #card_id_list >= 2 then
            table_insert(tmp_list,number)
            tmp_count = tmp_count + 1
        elseif tmp_count >= 3 then
            local number_list = check_shuang_shun_wight(real_card_number_set,tmp_list)
            local card_list = {}
            for _,number in pairs(number_list) do
                for count=1,2 do
                    local card = table_remove(real_card_number_set[number],1)
                    table_insert(card_list,card)
                end
                if #real_card_number_set[number] <= 0 then
                    real_card_number_set[number] = nil
                end
            end
            if #card_list > 0 then
                table_insert(card_type_list[CARD_SUIT_TYPE_SHUANGSHUN],card_list)
            end
            tmp_list = {}
            tmp_count = 0
        elseif tmp_count > 0 then
            tmp_list = {}
            tmp_count = 0
        end
        power = power + 1
    end

    --print("make_shuang_shun33333",get_now_ustime() - start_time)
end

local function select_card_type_list(uid,ddz_instance)
    local handle_count_one = get_card_handle_count(dan_shun_priority_list)
    local absolute_count_one = get_absolute_handle_count(uid,ddz_instance,dan_shun_priority_list)
    local weigh_value_one = get_card_weigh_value(dan_shun_priority_list)
    if absolute_count_one >= handle_count_one - 1 then --满足必赢条件
        return dan_shun_priority_list
    end

    local handle_count_two = get_card_handle_count(shuang_shun_priority_list)
    local absolute_count_two = get_absolute_handle_count(uid,ddz_instance,shuang_shun_priority_list)
    local weigh_value_two = get_card_weigh_value(shuang_shun_priority_list)
    if absolute_count_two >= handle_count_two - 1 then --满足必赢条件
        return shuang_shun_priority_list
    end

    local handle_count_three = get_card_handle_count(san_zhang_priority_list)
    local absolute_count_three = get_absolute_handle_count(uid,ddz_instance,san_zhang_priority_list)
    local weigh_value_three = get_card_weigh_value(san_zhang_priority_list)
    if absolute_count_three >= handle_count_three - 1 then --满足必赢条件
        return san_zhang_priority_list
    end

    local tmp_handle_count = weigh_value_one
    local tmp_card_list = dan_shun_priority_list
    local tmp_absolute_count = absolute_count_one
    local tmp_weigh_value = weigh_value_one

    if tmp_handle_count < handle_count_two then
        tmp_handle_count = handle_count_two
        tmp_card_list = shuang_shun_priority_list
        tmp_absolute_count = absolute_count_two
        tmp_weigh_value = weigh_value_two
    elseif tmp_handle_count == handle_count_two and tmp_absolute_count > absolute_count_two then
        tmp_card_list = shuang_shun_priority_list
        tmp_absolute_count = absolute_count_two
        tmp_weigh_value = weigh_value_two
    elseif tmp_handle_count == handle_count_two and tmp_absolute_count == absolute_count_two and
           tmp_weigh_value < weigh_value_two then
        tmp_card_list = shuang_shun_priority_list
        tmp_weigh_value = weigh_value_two
    end

    if tmp_handle_count < handle_count_three then
        tmp_handle_count = handle_count_three
        tmp_card_list = san_zhang_priority_list
        tmp_absolute_count = absolute_count_tree
        tmp_weigh_value = weigh_value_tree
    elseif tmp_handle_count == handle_count_three and tmp_absolute_count > absolute_count_three then
        tmp_card_list = san_zhang_priority_list
        tmp_absolute_count = absolute_count_three
        tmp_weigh_value = weigh_value_three
    elseif tmp_handle_count == handle_count_three and tmp_absolute_count == absolute_count_three and
           tmp_weigh_value < weigh_value_three then
        tmp_card_list = san_zhang_priority_list
        tmp_weigh_value = weigh_value_three
    end

    return tmp_card_list
end

-- 王炸 炸弹 顺子 飞机 连对 三带 对子 单牌
local function analyseb_card(cards_id_list,priority_list)
    local _,real_card_num_set = process_card_id_list(cards_id_list)
    local analyse_result = {}
    make_wangzha(real_card_num_set,priority_list)
    make_zhadan(real_card_num_set,priority_list) 
    make_sunzi_new(real_card_num_set,priority_list)
    make_shuang_shun(real_card_num_set,priority_list)
    -- make_sunzi_new(real_card_num_set,priority_list)
    make_feiji(real_card_num_set,priority_list)
    make_san_zhang_pai(real_card_num_set,priority_list)
    make_dui_pai(real_card_num_set,priority_list)
    make_dan_pai(real_card_num_set,priority_list)
end

local function reset_priority_list(priority_list)
    for i = 1 , 14 do
        priority_list[i] = {}
    end
end

local function clear_card_type_list()
        reset_priority_list(new_priority_list)
    -- new_priority_list = alloc_tmp_card_type_list()
    -- san_zhang_priority_list = alloc_tmp_card_type_list()
    -- dan_shun_priority_list =  alloc_tmp_card_type_list()
    -- shuang_shun_priority_list = alloc_tmp_card_type_list()
end

local function get_card_handle_count_new(card_type_list)
    local handle_count = 0 
    for _,card_list in pairs(card_type_list) do
        handle_count = handle_count + #card_list
    end
    return handle_count
end

make_card_type = function(uid,ddz_instance,dipai)
    local priority_list = {}
    reset_priority_list(priority_list)
    local wang_er = 0
    local cards_id_list = ddz_instance:get_player_card_ids(uid)
    if dipai then
        for _,card in pairs(dipai) do
            table_insert(cards_id_list,card)
        end
        for _,card in pairs(cards_id_list) do
            if get_card_logic_value(card) >= 14 then
                wang_er = wang_er + 1
            end
        end
    end
    dbglog(cards_id_list)
    analyseb_card(cards_id_list,priority_list)
    dbglog(cards_id_list,priority_list)
    return priority_list,get_card_handle_count_new(priority_list),ddz_instance:get_player_card_ids(uid),wang_er
end

-----------------------------------------make_card_type_end-------------------------------------

local function get_min_dan_pai_from_card_type()
   local dan_pai_list = self_card_type_list[CARD_SUIT_TYPE_DANPAI]
   if not next(dan_pai_list) then
       return
   end

   local min_dan_pai = dan_pai_list[1]
   for _,number in pairs(dan_pai_list) do

      if POWER_MAP[min_dan_pai] > POWER_MAP[number] then
         min_dan_pai = number
      end
   end
   return min_dan_pai
end

local function get_min_dui_pai_from_card_type()
    local dui_pai_list = self_card_type_list[CARD_SUIT_TYPE_DUIPAI]
    local min_dui_pai_num = dui_pai_list[1]
    if min_dui_pai_num then
       for _,number in pairs(dui_pai_list) do
          if POWER_MAP[min_dui_pai_num] > POWER_MAP[number] then
             min_dui_pai_num = number
          end
       end
   end
   return min_dui_pai_num
end

local function get_san_zhang_pai_xiao_pai()
   local min_dan_pai_num = get_min_dan_pai_from_card_type()
   local min_dui_pai_num = get_min_dui_pai_from_card_type()
   
   --大于两手牌的时候 不能带大于等于二的牌,写死算了
   local now_count = get_card_handle_count(self_card_type_list)
   if now_count >= 2 and min_dan_pai_num and POWER_MAP[min_dan_pai_num] >= 14 then
      dan_pai_num = nil
   end
   if now_count >= 2 and min_dui_pai_num and POWER_MAP[min_dui_pai_num] >= 14 then
      dui_pai_num = nil
   end
   return min_dan_pai_num,min_dui_pai_num
end

local function get_feiji_xiao_pai(card_list)
   local t_xiao_pai = {}
   local xiao_pai_count = #card_list
   local handle_count = get_card_handle_count(self_card_type_list)
   local pai_2 = 14
   --不够单牌的时候拆6连单顺以上的底牌
   local xiao_dan_pai_list = {}
   for _,number in pairs(self_card_type_list[CARD_SUIT_TYPE_DANPAI]) do
       if handle_count > 2 and POWER_MAP[number] >= pai_2 then
           goto continue
       end
       table_insert(xiao_dan_pai_list,number)

       ::continue::
   end
   for _,dan_shun in pairs(self_card_type_list[CARD_SUIT_TYPE_DANSHUN]) do
       if #dan_shun >= 6 then
           table_insert(xiao_dan_pai_list,dan_shun[1])
       end
   end
   if #xiao_dan_pai_list >= xiao_pai_count then
       for i=1,xiao_pai_count do
           t_xiao_pai[xiao_dan_pai_list[i]] = 1
       end
       return t_xiao_pai
   end

    --不够对子的时候拆4连对以上的底对
    local xiao_dui_pai_list = {}
    for _,number in pairs(self_card_type_list[CARD_SUIT_TYPE_DUIPAI]) do
       if handle_count > 2 and POWER_MAP[number] >= pai_2 then
           goto continue
       end
       table_insert(xiao_dui_pai_list,number)

       ::continue::
    end

    if #xiao_dui_pai_list >= xiao_pai_count then
       for i=1,xiao_pai_count do
           t_xiao_pai[xiao_dui_pai_list[i]] = 2
       end
       return t_xiao_pai
    end

    return {}
end

local function get_sidaier_xiao_pai(card_suit_type)
    local t_xiao_pai = {}
    if card_suit_type == CARD_SUIT_TYPE_SIDAIER and 
       #self_card_type_list[CARD_SUIT_TYPE_DANPAI] >= 2 then
         for i=1,2 do
             local number = self_card_type_list[CARD_SUIT_TYPE_DANPAI][i]
             t_xiao_pai[number] = 1
         end
    end

    if card_suit_type == CARD_SUIT_TYPE_SIDAIER and
       #self_card_type_list[CARD_SUIT_TYPE_DUIPAI] >= 2 then
        for i=1,2 do
           local number = self_card_type_list[CARD_SUIT_TYPE_DUIPAI][i]
           t_xiao_pai[number] = 2
        end
    end
    return t_xiao_pai
end

local function get_second_min_number(num_list)
    assert(#num_list >= 2)
    local min_num = num_list[1]
    local second_min_num = num_list[2]
    if second_min_num < min_num then
        min_num = num_list[2]
        second_min_num = num_list[1]
    end
    for i=3,#num_list do
        if num_list[i] < second_min_num then
            if num_list[i] < min_num then
                second_min_num = min_num
                min_num = num_list[i]
            else
               second_min_num = num_list[i]
            end
        end
    end
    return second_min_num
end

local function get_max_two_number(num_list)
    assert(#num_list >= 2)
    local max_num = num_list[1]
    local second_max_num = num_list[2]
    if second_max_num > max_num then
        max_num = num_list[2]
        second_max_num = num_list[1]
    end
    for i=3,#num_list do
        if num_list[i] > second_max_num then
            if num_list[i] > max_num then
                second_max_num = max_num
                max_num = num_list[i]
            else
               second_max_num = num_list[i]
            end
        end
    end
    return max_num,second_max_num
end

local function get_number_list(cards_id_list)
    assert(#cards_id_list > 0)

    local tmp_number_list = {}
    for _,card_id in pairs(cards_id_list) do
        local number = extract_card_number(card_id)
        table_insert(tmp_number_list,number)
    end
    return tmp_number_list
end

local function get_min_dan_pai(cards_id_list)
    assert(#cards_id_list > 0)

    local tmp_number_set = {}
    for _,card_id in pairs(cards_id_list) do
        local number = extract_card_number(card_id)
        tmp_number_set[number] = (tmp_number_set[number] or 0) + 1
    end
    
    --去掉炸弹
    local card_number_set = {}
    for number,count in pairs(tmp_number_set) do
        if count ~= 4 then
            card_number_set[number] = count
        end
    end

    local min_number = extract_card_number(cards_id_list[1])
    local min_power = POWER_MAP[min_number]
    for number,_ in pairs(card_number_set) do
        if min_power > POWER_MAP[number] then
            min_power = POWER_MAP[number]
            min_number = number
        end
    end

    return {[min_number] = 1} 
end

local function get_max_cards_greater_than_key(last_record)
    local card_type_list = self_card_type_list[last_record.card_suit_type]
    if not next(card_type_list) then
        return
    end

    local max_card_num = card_type_list[1]
    for _,number in pairs(card_type_list) do
        if POWER_MAP[number] > POWER_MAP[max_card_num] then
            max_card_num = number
        end
    end
    if POWER_MAP[max_card_num] <= POWER_MAP[last_record.key] then
        return
    end

    if last_record.card_suit_type == CARD_SUIT_TYPE_DANPAI then
        return {[max_card_num] = 1}
    elseif last_record.card_suit_type == CARD_SUIT_TYPE_DUIPAI then
        return {[max_card_num] = 2}
    end
end

local M = {}




-- function M.analyse_play(self)
--     local ddz_instance = assert(self.ddz_instance)
--     local last_record = ddz_instance:get_last_card_suit_ex()
--     local must_play = false
--     if not last_record or last_record.uid == self.uid then
--         must_play = true
--     end
--     xiajia_uid = self.ddz_instance:get_next_position_uid(self.uid)
--     shangjia_uid = self.ddz_instance:get_next_position_uid(xiajia_uid)
--     --确定牌型
--     self_card_type_list = assert(make_card_type(self.uid,ddz_instance)) 
--     shangjia_card_type_list  = assert(make_card_type(shangjia_uid,ddz_instance))        --上家的手牌  分析过后的牌组
--     xiajia_card_type_list   = assert(make_card_type(xiajia_uid,ddz_instance))         --下家的手牌  分析过后的牌组
--     dbglog(self_card_type_list)
--     dbglog(shangjia_card_type_list)
--     dbglog(xiajia_card_type_list)

--     local result_card_id_list
--     if must_play then
--         --先手出牌
--         result_card_id_list = on_must_play(self) or {}
--     else
--         --后手出牌
--         result_card_id_list = on_not_must_play(self,last_record) or {}
--     end
    
--     dbglog(result_card_id_list)
--     return {card_suit = result_card_id_list}
-- end
------------------------------------------------------------------------------------------------------------------------------------------------
--对比牌型
local function compare_card(first_card_list,next_card_list)

end

local function get_card_count(card_type_list)
    local card_count = 0
    for _,type_list in pairs(card_type_list) do 
        for _,card_list in pairs(type_list) do
            card_count  = card_count + #card_list
        end
    end
    return card_count
end

local function check_danpai_max_small(card,didui_card_id_list)
    for _,value in pairs(didui_card_id_list) do
        for _,card_id in pairs(value) do
            if get_card_logic_value(card) < get_card_logic_value(card_id) then
                return true
            end
        end
    end
    return false
end

local function check_duipai_max_small(card,didui_card_id_list)
    for _,value in pairs(didui_card_id_list) do
        local number_count_list = process_card_id_list(value)
        for number,count in pairs(number_count_list) do
            if count >= 2 and get_card_logic_value(card) < POWER_MAP[number] then
                return true
            end
        end
    end
    return false
end

-- local CARD_SUIT_TYPE_INVALID = 0         --无效牌型
-- local CARD_SUIT_TYPE_WANGZHA = 1         --王炸
-- local CARD_SUIT_TYPE_ZHADAN = 2          --炸弹
-- local CARD_SUIT_TYPE_DANPAI = 3          --单牌
-- local CARD_SUIT_TYPE_DUIPAI = 4          --对牌
-- local CARD_SUIT_TYPE_SANZANGPAI = 5      --三张牌
-- local CARD_SUIT_TYPE_SANDAIYI = 6        --三带一
-- local CARD_SUIT_TYPE_DANSHUN = 7         --单顺
-- local CARD_SUIT_TYPE_SHUANGSHUN = 8      --双顺
-- local CARD_SUIT_TYPE_FEIJI = 9           --飞机
-- local CARD_SUIT_TYPE_FEIJIDAICIBANG = 10 --飞机带翅膀
-- local CARD_SUIT_TYPE_SIDAIER = 11        --四带二
-- local CARD_SUIT_TYPE_RUANZHA = 12        --软炸
-- local CARD_SUIT_TYPE_SANDAIYIDUI = 13    --三带一对
-- local CARD_SUIT_TYPE_SIDAILIANGDUI = 14  --四带两对

--分析手牌  同牌型大牌数量  同牌型小牌数量  绝对大牌数量 card_type_list自己的手牌分布 didui_card_type_list敌对的手牌分部集合 (三带和拖拉机处理有缺陷)
local function analyse_card_type_list(card_type_list,didui_card_type_list,didui_card_id_list)
    -- dbglog(self_card_type_list,didui_card_type_list,didui_uid_list)
    local max_big_card_list = {}
    local big_card_list = {}
    local small_card_list = {}
    local didui_have_boom = false
    local didui_have_wangzha = false
    for _,type_list in pairs(didui_card_type_list) do
        if #type_list[CARD_SUIT_TYPE_WANGZHA] > 0 then
            didui_have_wangzha = true
        end
        if #type_list[CARD_SUIT_TYPE_ZHADAN] > 0 then
            didui_have_boom = true
        end   
    end

    for card_type,value in pairs(card_type_list) do
        for _,self_card_list in pairs(value) do
            if card_type == CARD_SUIT_TYPE_WANGZHA then
                max_big_card_list[card_type] = max_big_card_list[card_type] or {}
                table_insert(max_big_card_list[card_type],self_card_list)
            elseif card_type == CARD_SUIT_TYPE_DANPAI then
                local small = check_danpai_max_small(self_card_list[1],didui_card_id_list)

                 if small then
                    small_card_list[card_type] = small_card_list[card_type] or {}
                    table_insert(small_card_list[card_type],self_card_list)
                elseif didui_have_wangzha or didui_have_boom then
                    big_card_list[card_type] = big_card_list[card_type] or {}
                    table_insert(big_card_list[card_type],self_card_list)
                else
                    max_big_card_list[card_type] = max_big_card_list[card_type] or {}
                    table_insert(max_big_card_list[card_type],self_card_list)
                end     
            elseif card_type == CARD_SUIT_TYPE_DUIPAI then
                local small = check_duipai_max_small(self_card_list[1],didui_card_id_list)

                if small then
                    small_card_list[card_type] = small_card_list[card_type] or {}
                    table_insert(small_card_list[card_type],self_card_list)
                elseif didui_have_wangzha or didui_have_boom then
                    big_card_list[card_type] = big_card_list[card_type] or {}
                    table_insert(big_card_list[card_type],self_card_list)
                else
                    max_big_card_list[card_type] = max_big_card_list[card_type] or {}
                    table_insert(max_big_card_list[card_type],self_card_list)
                end                

            elseif card_type == CARD_SUIT_TYPE_ZHADAN then
                local small = false
                for _,didui_value in pairs(didui_card_type_list) do
                    for _,didui_type_list in pairs(didui_value[card_type]) do
                        if get_card_logic_value(didui_type_list[1]) > get_card_logic_value(self_card_list[1]) then
                            small = true
                            break
                        end
                    end
                end
                if small or didui_have_wangzha then
                    big_card_list[card_type] = big_card_list[card_type] or {}
                    table_insert(big_card_list[card_type],self_card_list)
                else
                    max_big_card_list[card_type] = max_big_card_list[card_type] or {}
                    table_insert(max_big_card_list[card_type],self_card_list)
                end
            else
                local small = false
                for _,didui_value in pairs(didui_card_type_list) do
                    -- dbglog(didui_value)
                    for _,didui_type_list in pairs(didui_value[card_type]) do
                        -- dbglog(didui_type_list)
                        if  card_type == CARD_SUIT_TYPE_DANSHUN or card_type == CARD_SUIT_TYPE_SHUANGSHUN then
                            dbglog(didui_type_list,self_card_list)
                            if get_card_logic_value(didui_type_list[#didui_type_list]) > get_card_logic_value(self_card_list[#self_card_list]) and #didui_type_list >= #self_card_list then
                                small = true
                                break        
                            end
                        elseif get_card_logic_value(didui_type_list[1]) > get_card_logic_value(self_card_list[1]) then
                            small = true
                            break
                        end
                    end                    
                end
                
                if small then
                    small_card_list[card_type] = small_card_list[card_type] or {}
                    table_insert(small_card_list[card_type],self_card_list)
                elseif didui_have_wangzha or didui_have_boom then
                    big_card_list[card_type] = big_card_list[card_type] or {}
                    table_insert(big_card_list[card_type],self_card_list)
                else
                    max_big_card_list[card_type] = max_big_card_list[card_type] or {}
                    table_insert(max_big_card_list[card_type],self_card_list)
                end  
            end
        end
    end
    local max_big_handle_count = get_card_handle_count_new(max_big_card_list)
    local big_handle_count = get_card_handle_count_new(big_card_list)
    local small_handle_count = get_card_handle_count_new(small_card_list)
    return max_big_card_list,big_card_list,small_card_list,max_big_handle_count,big_handle_count,small_handle_count
end


--先手出牌绝对大牌出完
function M.first_abs_win(self)

    return false,nil
end

--后手出牌绝对大牌出完
function M.last_abs_win(self)
    return false,nil
end

--获得一手最小牌 
local function get_min_hander(card_type_list,alert_list,didui_card_count)
    local min_weight = 0
    local ret_card_list = {}
    for card_type ,value_list in pairs(card_type_list) do
        for _,card_list in pairs(value_list) do
            if alert_list and alert_list[card_type] and #alert_list[card_type][1] == #card_list and get_card_logic_value(alert_list[card_type][1][1]) > get_card_logic_value(card_list[1]) then
                goto continue
            end
            local weight = get_card_logic_value(card_list[1])
            if card_type == CARD_SUIT_TYPE_WANGZHA then
                weight = weight + 200
            end
           if card_type == CARD_SUIT_TYPE_ZHADAN then
                weight = weight + 100
            end

            for _,count in pairs(didui_card_count) do
                if count == #card_list then
                    weight = weight + 50
                end
            end

            if min_weight == 0 or weight < min_weight then
                min_weight = weight
                ret_card_list = card_list
            end
            ::continue::
        end
    end
    return ret_card_list
end

--出最小单牌
local function get_min_card(self)
    local cards_id_list = self.ddz_instance:get_player_card_ids(self.uid)
    local min_card_clv = 0
    local min_card
    for _,card in pairs(cards_id_list) do
        local card_clv = get_card_logic_value(card)
        if min_card_clv == 0 or card_clv < min_card_clv then
            min_card = card
        end
    end
    return {min_card}
end

--地主 获得农民报单手牌
local function check_alert_list(didui_card_type_list)
    local alert_list = {}
    for _,card_type_list in pairs(didui_card_type_list) do
        local handle_count = get_card_handle_count_new(card_type_list)
        if handle_count == 1 then
            for card_type,card_list in pairs(card_type_list) do
                if #card_list > 0 then
                    if not alert_list[card_type] or get_card_logic_value(card_list[1][1]) > get_card_logic_value(alert_list[card_type][1][1]) then
                        dbglog(card_list)
                        alert_list[card_type] = card_list
                    end
                    break
                end
            end
        end
    end
    dbglog(alert_list)
    return alert_list
end

-- local CARD_SUIT_TYPE_INVALID = 0         --无效牌型
-- local CARD_SUIT_TYPE_WANGZHA = 1         --王炸
-- local CARD_SUIT_TYPE_ZHADAN = 2          --炸弹
-- local CARD_SUIT_TYPE_DANPAI = 3          --单牌
-- local CARD_SUIT_TYPE_DUIPAI = 4          --对牌
-- local CARD_SUIT_TYPE_SANZANGPAI = 5      --三张牌
-- local CARD_SUIT_TYPE_SANDAIYI = 6        --三带一
-- local CARD_SUIT_TYPE_DANSHUN = 7         --单顺
-- local CARD_SUIT_TYPE_SHUANGSHUN = 8      --双顺
-- local CARD_SUIT_TYPE_FEIJI = 9           --飞机
-- local CARD_SUIT_TYPE_FEIJIDAICIBANG = 10 --飞机带翅膀
-- local CARD_SUIT_TYPE_SIDAIER = 11        --四带二
-- local CARD_SUIT_TYPE_RUANZHA = 12        --软炸
-- local CARD_SUIT_TYPE_SANDAIYIDUI = 13    --三带一对
-- local CARD_SUIT_TYPE_SIDAILIANGDUI = 14  --四带两对

local function force_out_feiji(self,self_card_type_list,last_record,alert_list)
    local card_suit = last_record.card_suit
    local card_clv = get_card_logic_value(card_suit[1])

    for _,card_list in ipairs(self_card_type_list[CARD_SUIT_TYPE_FEIJI]) do
        if #card_list > #card_suit and get_card_logic_value(card_list[1]) > card_clv then
            local ret_card_list = {}
            for i = 1, #card_suit do
                table_insert(ret_card_list,card_list[i])
            end
            return ret_card_list
        end  
    end 
end

local function force_out_shuangshun(self,self_card_type_list,last_record,alert_list)
    local card_suit = last_record.card_suit
    local card_clv = get_card_logic_value(card_suit[1])

    for _,card_list in ipairs(self_card_type_list[CARD_SUIT_TYPE_SHUANGSHUN]) do
        if #card_list > #card_suit and get_card_logic_value(card_list[1]) > card_clv then
            local ret_card_list = {}
            for i = 1, #card_suit do
                table_insert(ret_card_list,card_list[i])
            end
            return ret_card_list
        end  
    end 
end

local function get_good_shunzi(number_list,real_card_num_set,card_count)
    local max_weight = 0
    local ret_number_list = {}
    for i = 1 ,#number_list - card_count + 1 do
        local weight = 0 
        local key = false
        local temp_number_list = {}
        for j = 1, card_count do
            local number = number_list[i + j - 1]
            table_insert(temp_number_list, number)
            if #real_card_num_set[number] == 4 then
                key = true
                break
            end
            if #real_card_num_set[number] == 3 then
                weight = weight - 3
            end
            if #real_card_num_set[number] == 2 then
                weight = weight - 2
            end
        end

        if not key then
            if max_weight == 0 or weight > max_weight then
                max_weight = weight
                ret_number_list = temp_number_list
            end
        end
    end

    if #ret_number_list ~= card_count then 
        return false
    end

    local card_list = {}
    for _,number in ipairs(ret_number_list) do
        local card = table_remove(real_card_num_set[number],1)
        table_insert(card_list,card)
    end
    return true,card_list
end

local function force_out_danshun(self,self_card_type_list,last_record,alert_list)
    local card_suit = last_record.card_suit
    local card_clv = POWER_MAP[last_record.key]

    local cards_id_list = self.ddz_instance:get_player_card_ids(self.uid)
    local _,real_card_num_set = process_card_id_list(cards_id_list)
    local number_list = {}

    local power = 1
    while true do
        local number = CONTINUOUS_CARD_MAP[power]
        if not number then
            break 
        end

        if real_card_num_set[number] then
            table_insert(number_list,number)
        else
            if #number_list >= #card_suit and POWER_MAP[number_list[1]] > card_clv then
                local ok,ret = get_good_shunzi(number_list,real_card_num_set,#card_suit)
                if ok then return ret end
            end
            number_list = {}
        end
        power = power + 1

    end

end

--收集可拆对子
local function get_duizi(self,self_card_type_list,card_clv)
    for _,card_list in ipairs(self_card_type_list[CARD_SUIT_TYPE_SHUANGSHUN]) do
        if #card_list > 3 then
            return {card_list[1],card_list[2]}
        end  
    end 

    local dan_pai = {}
    --从三带一里面收集一个带牌
    for _,card_list in ipairs(self_card_type_list[CARD_SUIT_TYPE_SANDAIYI]) do
        if get_card_logic_value(card_list[#card_list]) > card_clv then
            table_insert(dan_pai, card_list[#card_list])
        end  
    end 

    for _,card_list in ipairs(self_card_type_list[CARD_SUIT_TYPE_DANPAI]) do
        if get_card_logic_value(card_list[1]) > card_clv then
            table_insert(dan_pai, card_list[1])
        end  
    end

    --在顺子里面找组合
   for _,card_list in ipairs(self_card_type_list[CARD_SUIT_TYPE_DANSHUN]) do
        --只拆顺子头部两张
        local shun_card = card_list[1]
        local shun_card_clv = get_card_logic_value(shun_card)
        if #card_list > 5 then
            for _, card in pairs(dan_pai) do
                if shun_card_clv == get_card_logic_value(card) then
                    return {card,shun_card}
                end
            end
        end

        shun_card = card_list[2]
        shun_card_clv = get_card_logic_value(shun_card)
        if #card_list > 6 then
            for _, card in pairs(dan_pai) do
                if shun_card_clv == get_card_logic_value(card) then
                    return {card,shun_card}
                end
            end
        end

        shun_card = card_list[#card_list]
        local shun_card_clv = get_card_logic_value(shun_card)
        if #card_list > 5 then
            for _, card in pairs(dan_pai) do
                if shun_card_clv == get_card_logic_value(card) then
                    return {card,shun_card}
                end
            end
        end

        shun_card = card_list[#card_list - 1]
        shun_card_clv = get_card_logic_value(shun_card)
        if #card_list > 6 then
            for _, card in pairs(dan_pai) do
                if shun_card_clv == get_card_logic_value(card) then
                    return {card,shun_card}
                end
            end
        end
    end  
end

local function force_out_sandaiyidui(self,self_card_type_list,last_record,alert_list)
    local card_suit = last_record.card_suit
    local card_clv = POWER_MAP[last_record.key]

    for _,card_list in ipairs(self_card_type_list[CARD_SUIT_TYPE_FEIJIDAICIBANG]) do
        if #card_list % #card_suit == 0 and get_card_logic_value(card_list[1]) > card_clv then
            return {card_list[1],card_list[2],card_list[3],card_list[#card_list],card_list[#card_list-1]}
        end
    end

    for _,card_list in ipairs(self_card_type_list[CARD_SUIT_TYPE_SANZANGPAI]) do
        if get_card_logic_value(card_list[1]) > card_clv then
            if #self_card_type_list[CARD_SUIT_TYPE_SANDAIYIDUI] > 0 then
                local sandaidui_card_list = self_card_type_list[CARD_SUIT_TYPE_SANDAIYIDUI][1]
                return {card_list[1],card_list[2],card_list[3],sandaidui_card_list[4],sandaidui_card_list[5]}
            end
            if #self_card_type_list[CARD_SUIT_TYPE_DUIPAI] > 0 then
                return {card_list[1],card_list[2],card_list[3],self_card_type_list[CARD_SUIT_TYPE_DANPAI][1][1],self_card_type_list[CARD_SUIT_TYPE_DANPAI][1][2]}
            end
            local duizi = get_duizi(self,self_card_type_list,card_clv)
            if duizi then
                return {card_list[1],card_list[2],card_list[3],duizi[1],duizi[2]}
            end
        end  
    end 

    for _,card_list in ipairs(self_card_type_list[CARD_SUIT_TYPE_SANDAIYI]) do
        if get_card_logic_value(card_list[1]) > card_clv then
            if #self_card_type_list[CARD_SUIT_TYPE_SANDAIYIDUI] > 0 then
                local sandaidui_card_list = self_card_type_list[CARD_SUIT_TYPE_SANDAIYIDUI][1]
                return {card_list[1],card_list[2],card_list[3],sandaidui_card_list[4],sandaidui_card_list[5]}
            end
            local duizi = get_duizi(self,self_card_type_list,card_clv)
            if duizi then
                return {card_list[1],card_list[2],card_list[3],duizi[1],duizi[2]}
            end
        end  
    end 
end

local function force_out_sandaiyi(self,self_card_type_list,last_record,alert_list)
    local card_suit = last_record.card_suit
    local card_clv = get_card_logic_value(card_suit[1])

    dbglog(self_card_type_list,card_suit,card_clv)

    for _,card_list in ipairs(self_card_type_list[CARD_SUIT_TYPE_SANDAIYIDUI]) do
        if get_card_logic_value(card_list[1]) > card_clv then
            return {card_list[1],card_list[2],card_list[3],card_list[4]}
        end  
    end 

    for _,card_list in ipairs(self_card_type_list[CARD_SUIT_TYPE_FEIJIDAICIBANG]) do
        if get_card_logic_value(card_list[1]) > card_clv then
            return {card_list[1],card_list[2],card_list[3],card_list[#card_list]}
        end  
    end 

    for _,card_list in ipairs(self_card_type_list[CARD_SUIT_TYPE_SANZANGPAI]) do
        if get_card_logic_value(card_list[1]) > card_clv then
            if #self_card_type_list[CARD_SUIT_TYPE_SANDAIYI] > 0 then
                local sandaiyi_card_list = self_card_type_list[CARD_SUIT_TYPE_SANDAIYI][1]
                return {card_list[1],card_list[2],card_list[3],sandaiyi_card_list[4]}
            end

            if #self_card_type_list[CARD_SUIT_TYPE_SANDAIYIDUI] > 0 then
                local sandaidui_card_list = self_card_type_list[CARD_SUIT_TYPE_SANDAIYIDUI][1]
                return {card_list[1],card_list[2],card_list[3],sandaidui_card_list[5]}
            end

            --拆一个顺子带出去
            if #self_card_type_list[CARD_SUIT_TYPE_DANSHUN] > 0 then
                for _,shun_card_list in ipairs(self_card_type_list[CARD_SUIT_TYPE_DANSHUN]) do
                    if #shun_card_list > 5 then
                        return {card_list[1],card_list[2],card_list[3],shun_card_list[1]}
                    end
                end
            end
            if #self_card_type_list[CARD_SUIT_TYPE_DANPAI] > 0 then
                return {card_list[1],card_list[2],card_list[3],self_card_type_list[CARD_SUIT_TYPE_DANPAI][1][1]}
            end
            if #self_card_type_list[CARD_SUIT_TYPE_DUIPAI] > 0 then
                return {card_list[1],card_list[2],card_list[3],self_card_type_list[CARD_SUIT_TYPE_DANPAI][1][1]}
            end
        end  
    end 

end

--强行拆出三张牌
local function force_out_sanzhangpai(self,self_card_type_list,last_record,alert_list)
    local card_suit = last_record.card_suit
    local card_clv = get_card_logic_value(card_suit[1])
    for _,card_list in ipairs(self_card_type_list[CARD_SUIT_TYPE_SANDAIYI]) do
        if get_card_logic_value(card_list[1]) > card_clv then
            return {card_list[1],card_list[2],card_list[3]}
        end  
    end 

    for _,card_list in ipairs(self_card_type_list[CARD_SUIT_TYPE_SANDAIYIDUI]) do
        if get_card_logic_value(card_list[1]) > card_clv then
            return {card_list[1],card_list[2],card_list[3]}
        end  
    end 
end

--强行拆对子
local function force_out_duipai(self,self_card_type_list,last_record,alert_list)
    local card_suit = last_record.card_suit
    local card_clv = get_card_logic_value(card_suit[1])
    if alert_list[CARD_SUIT_TYPE_DANPAI] and get_card_logic_value(alert_list[CARD_SUIT_TYPE_DANPAI][1][1]) > card_clv then
        card_clv = get_card_logic_value(alert_list[CARD_SUIT_TYPE_DANPAI][1][1])
    end   

    --先从 三带对 里面拆
    for _,card_list in ipairs(self_card_type_list[CARD_SUIT_TYPE_SANDAIYIDUI]) do
        if get_card_logic_value(card_list[#card_list]) > card_clv then
            return {card_list[#card_list],card_list[#card_list - 1]}
        end
    end   
    --从飞机带翅膀里面拆
    for _,card_list in ipairs(self_card_type_list[CARD_SUIT_TYPE_FEIJIDAICIBANG]) do
        if #card_list %5 == 0 and get_card_logic_value(card_list[#card_list]) > card_clv then
            return {card_list[#card_list],card_list[#card_list - 1]}
        end
    end 

    --从 连对 里面拆
    for _,card_list in ipairs(self_card_type_list[CARD_SUIT_TYPE_SHUANGSHUN]) do
        for i = 1,#card_suit,2 do
            if get_card_logic_value(card_list[i]) > card_clv and get_card_logic_value(card_list[i]) > 9 then
                return {card_list[i],card_list[i + 1]}
            end
        end
    end 

    --从 三带 一 单排 顺子里面 组合
    --收集 三代一 的单牌
    local dan_pai = {}
    --从三带一里面收集一个带牌
    for _,card_list in ipairs(self_card_type_list[CARD_SUIT_TYPE_SANDAIYI]) do
        if get_card_logic_value(card_list[#card_list]) > card_clv then
            table_insert(dan_pai, card_list[#card_list])
        end  
    end 

    for _,card_list in ipairs(self_card_type_list[CARD_SUIT_TYPE_DANPAI]) do
        if get_card_logic_value(card_list[1]) > card_clv then
            table_insert(dan_pai, card_list[1])
        end  
    end

    --在顺子里面找组合
   for _,card_list in ipairs(self_card_type_list[CARD_SUIT_TYPE_DANSHUN]) do
        --只拆顺子头部两张
        local shun_card = card_list[#card_list]
        local shun_card_clv = get_card_logic_value(shun_card)
        if #card_list > 5 and shun_card_clv > card_clv then
            for _, card in pairs(dan_pai) do
                if shun_card_clv == get_card_logic_value(card) then
                    return {card,shun_card}
                end
            end
        end

        shun_card = card_list[#card_list - 1]
        shun_card_clv = get_card_logic_value(shun_card)
        if #card_list > 6 and shun_card_clv > card_clv then
            for _, card in pairs(dan_pai) do
                if shun_card_clv == get_card_logic_value(card) then
                    return {card,shun_card}
                end
            end
        end
    end  

     --从三张牌里面拆一对
    for _,card_list in ipairs(self_card_type_list[CARD_SUIT_TYPE_SANDAIYIDUI]) do
        if get_card_logic_value(card_list[#card_list]) > card_clv then
            return {card_list[#card_list],card_list[#card_list - 1]}
        end
    end 

    local cards_id_list = self.ddz_instance:get_player_card_ids(self.uid)
    local _,real_card_num_set = process_card_id_list(cards_id_list)

    --拆2
    if real_card_num_set[CARD_TWO_NUMBER] and card_clv < 14 and #real_card_num_set[CARD_TWO_NUMBER] >= 2 then
        return {real_card_num_set[CARD_TWO_NUMBER][1],real_card_num_set[CARD_TWO_NUMBER][2]}
    end

end

--强行拆牌压单
local function force_out_danpai(self,self_card_type_list,last_record,alert_list)
    local card = last_record.card_suit[1]
    local card_clv = get_card_logic_value(card)
    if alert_list[CARD_SUIT_TYPE_DANPAI] and get_card_logic_value(alert_list[CARD_SUIT_TYPE_DANPAI][1][1]) > card_clv then
        card_clv = get_card_logic_value(alert_list[CARD_SUIT_TYPE_DANPAI][1][1])
    end
    --先从 顺子头部拆一个单出来
    for _,card_list in ipairs(self_card_type_list[CARD_SUIT_TYPE_DANSHUN]) do
        if #card_list > 5 and get_card_logic_value(card_list[#card_list]) > card_clv then
            return {card_list[#card_list]}
        end
    end
    --从三带一里面拆一个带牌
    for _,card_list in ipairs(self_card_type_list[CARD_SUIT_TYPE_SANDAIYI]) do
        if get_card_logic_value(card_list[#card_list]) > card_clv then
            return {card_list[#card_list]}
        end
    end   

    --从对子里面拆一个
    for _,card_list in ipairs(self_card_type_list[CARD_SUIT_TYPE_DUIPAI]) do
        if get_card_logic_value(card_list[#card_list]) > card_clv then
            return {card_list[#card_list]}
        end
    end  


    --从三带对里面拆一个
    for _,card_list in ipairs(self_card_type_list[CARD_SUIT_TYPE_SANDAIYIDUI]) do
        if get_card_logic_value(card_list[#card_list]) > card_clv then
            return {card_list[#card_list]}
        end
    end 

     --从三张牌里面拆一个
    for _,card_list in ipairs(self_card_type_list[CARD_SUIT_TYPE_SANDAIYIDUI]) do
        if get_card_logic_value(card_list[#card_list]) > card_clv then
            return {card_list[#card_list]}
        end
    end 

    local cards_id_list = self.ddz_instance:get_player_card_ids(self.uid)
    local _,real_card_num_set = process_card_id_list(cards_id_list)

    --拆2
    if real_card_num_set[CARD_TWO_NUMBER] and card_clv < 14 and #real_card_num_set[CARD_TWO_NUMBER] >= 1 then
        return {real_card_num_set[CARD_TWO_NUMBER][1]}
    end

    if #self_card_type_list[CARD_SUIT_TYPE_WANGZHA] == 0 then
        --找王
       if real_card_num_set[BLACK_JOKER_NUMBER] and card_clv < 16 and #real_card_num_set[BLACK_JOKER_NUMBER] >= 1 then
            return {real_card_num_set[BLACK_JOKER_NUMBER][1]}
        end
        
        if real_card_num_set[RED_JOKER_NUMBER] and card_clv < 18 and #real_card_num_set[RED_JOKER_NUMBER] >= 1 then
            return {real_card_num_set[RED_JOKER_NUMBER][1]}
        end 
    end
end    

--强行拆牌 压单压对子
local function force_out_dan_dui(self,last_record,alert_list)

    local cards_id_list = self.ddz_instance:get_player_card_ids(self.uid)
    local _,real_card_num_set = process_card_id_list(cards_id_list)
    local card_suit_type = last_record.card_suit_type
    local card = last_record.card_suit[1]
    local card_clv = get_card_logic_value(card)

    if card_suit_type == CARD_SUIT_TYPE_DANPAI then
        local power = 1
        while true do
            local number = CONTINUOUS_CARD_MAP[power]
            if not number then
                break 
            end

            if real_card_num_set[number] and POWER_MAP[number] > card_clv then
                return {real_card_num_set[number][1]}
            end
            power = power + 1
        end
    elseif card_suit_type == CARD_SUIT_TYPE_DUIPAI then 
        local power = 1
        while true do
            local number = CONTINUOUS_CARD_MAP[power]
            if not number then
                break 
            end

            if real_card_num_set[number] and #real_card_num_set[number] >=2 and POWER_MAP[number] > card_clv then
                return {real_card_num_set[number][1],real_card_num_set[number][2]}
            end
            power = power + 1
        end
    end
end

--牺牲一个权重拆手牌压
local function force_out_card(self,self_card_type_list,last_record,alert_list)
    local card_suit_type = last_record.card_suit_type
    if card_suit_type == CARD_SUIT_TYPE_DANPAI then
        return force_out_danpai(self,self_card_type_list,last_record,alert_list)
    elseif card_suit_type == CARD_SUIT_TYPE_DUIPAI then 
        return force_out_duipai(self,self_card_type_list,last_record,alert_list)
    elseif card_suit_type == CARD_SUIT_TYPE_SANZANGPAI then
        return force_out_sanzhangpai(self,self_card_type_list,last_record,alert_list)
    elseif card_suit_type == CARD_SUIT_TYPE_SANDAIYI then
        return force_out_sandaiyi(self,self_card_type_list,last_record,alert_list)
    elseif card_suit_type == CARD_SUIT_TYPE_SANDAIYIDUI then
        return force_out_sandaiyidui(self,self_card_type_list,last_record,alert_list)
    elseif card_suit_type == CARD_SUIT_TYPE_DANSHUN then
        return force_out_danshun(self,self_card_type_list,last_record,alert_list)
    elseif card_suit_type == CARD_SUIT_TYPE_SHUANGSHUN then
        return force_out_shuangshun(self,self_card_type_list,last_record,alert_list)
    elseif card_suit_type == CARD_SUIT_TYPE_FEIJI then
        return force_out_feiji(self,self_card_type_list,last_record,alert_list)
    elseif card_suit_type == CARD_SUIT_TYPE_FEIJIDAICIBANG then

    elseif card_suit_type == CARD_SUIT_TYPE_SIDAIER then

    end
end

--地主先手出牌
function dizhu_first_play(self)
    local didui_card_type_list = {shangjia_card_type_list,xiajia_card_type_list}
    local didui_card_id_list = {shangjia_card_id_list,xiajia_card_id_list}
    local didui_card_count = {#shangjia_card_id_list,#xiajia_card_id_list}
    dbglog(self_card_handle_count)
    --最后一手牌 打掉
    if self_card_handle_count == 1 then
        dbglog("最后一手牌")
        return get_min_hander(self_card_type_list,nil,didui_card_count)
    end

    --绝对大牌 大牌 小牌
    local max_big_card_list,big_card_list,small_card_list,max_big_handle_count,big_handle_count,small_handle_count = analyse_card_type_list(self_card_type_list,didui_card_type_list,didui_card_id_list)
    dbglog(max_big_card_list,big_card_list,small_card_list,max_big_handle_count,big_handle_count,small_handle_count)
    --只有一手 大牌 小牌 出绝对大牌 
    if big_handle_count + small_handle_count == 1 then
        dbglog("最后一手不是绝对大牌")
        return get_min_hander(max_big_card_list,nil,didui_card_count)
    end

    --农民爆单牌型
    local alert_list = check_alert_list(didui_card_type_list)

    --出非敌方爆单牌型的小牌，优先出 大牌里面有相同牌型的，否则出最小牌型牌
    --寻找合适的小牌
    local max_weight = -100
    local ret_card_list = {}
    for card_type,type_list in pairs(small_card_list) do
        for _,card_list in pairs(type_list) do
            if card_type == CARD_SUIT_TYPE_ZHADAN  then
                break
            end
            local key = true
            --排除报单牌型
            for alert_card_type,alert_card_list in pairs(alert_list) do
                if #alert_card_list[1] == #card_list and alert_card_type == card_type and get_card_logic_value(alert_card_list[1][1]) > get_card_logic_value(card_list[1]) then
                    key = false
                end
            end
            if key then
                local weight = 0 - get_card_logic_value(card_list[1])
                weight = weight + #card_list
                if max_big_card_list[card_type] and #max_big_card_list[card_type] > 0 and get_card_logic_value(card_list[1]) < 10 then
                    weight = weight + 100
                end

                if big_card_list[card_type] and #big_card_list[card_type] > 0 and get_card_logic_value(card_list[1]) < 10 then
                    weight = weight + 100
                end 

                weight = weight + #self_card_type_list[card_type] * 10

                if get_card_logic_value(card_list[1]) >= 14 then
                    weight = weight - 100
                end

                if card_type == CARD_SUIT_TYPE_DANSHUN or card_type == CARD_SUIT_TYPE_SHUANGSHUN  then
                    weight = weight + 50
                end 

                if weight > max_weight then 
                    max_weight = weight
                    ret_card_list = card_list
                end
            end
        end
    end

    --大牌中，值小余 10 的牌
    for card_type,type_list in pairs(big_card_list) do
        for _,card_list in pairs(type_list) do
            if card_type == CARD_SUIT_TYPE_WANGZHA or card_type == CARD_SUIT_TYPE_ZHADAN  then
                break
            end
            local weight = 0 - get_card_logic_value(card_list[1]) 
            weight = weight + #card_list
            if (card_type == CARD_SUIT_TYPE_FEIJI or card_type == CARD_SUIT_TYPE_FEIJIDAICIBANG) and self_card_handle_count <= 3 then
                weight = weight + 200
            end
           if get_card_logic_value(card_list[1]) < 8 then
                weight = weight + 150
           end
          if weight > max_weight then 
                max_weight = weight
                ret_card_list = card_list
            end
        end
    end

    for card_type,type_list in pairs(max_big_card_list) do
        for _,card_list in pairs(type_list) do
            if card_type == CARD_SUIT_TYPE_WANGZHA or card_type == CARD_SUIT_TYPE_ZHADAN  then
                break
            end
            local weight = 0 - get_card_logic_value(card_list[1]) 
            weight = weight + #card_list
            if (card_type == CARD_SUIT_TYPE_FEIJI or card_type == CARD_SUIT_TYPE_FEIJIDAICIBANG) and self_card_handle_count <= 3 then
                weight = weight + 200
            end
            if get_card_logic_value(card_list[1]) < 7  then
                weight = weight + 150
            end
            if weight > max_weight then 
                max_weight = weight
                ret_card_list = card_list
            end
        end
    end

    for card_type,type_list in pairs(self_card_type_list) do
        for _,card_list in pairs(type_list) do
            local weight = 0 - get_card_logic_value(card_list[1])

            if (card_type == CARD_SUIT_TYPE_DANSHUN and get_card_logic_value(card_list[#card_list]) < 11 ) or (card_type == CARD_SUIT_TYPE_SHUANGSHUN and get_card_logic_value(card_list[#card_list]) < 9) or (card_type == CARD_SUIT_TYPE_FEIJIDAICIBANG and get_card_logic_value(card_list[1]) < 9) then
                weight = weight + 150
            else
                break
            end

            if get_card_logic_value(card_list[1]) >= 13 then
                weight = weight - 100
            end

            if weight > max_weight then 
                max_weight = weight
                ret_card_list = card_list
            end


        end
    end


    if #ret_card_list > 0 then
        dbglog("出能接回来的小牌",ret_card_list)
        return ret_card_list
    end

    --小牌没有找到合适的牌从大牌和绝对大牌中选最小的牌打
    max_weight = 0
    for card_type,type_list in pairs(big_card_list) do
        for _,card_list in pairs(type_list) do
            local weight = 0 - get_card_logic_value(card_list[1])
            if max_big_card_list[card_type] and #max_big_card_list[card_type] > 0 then
                weight = weight + 100
            end

            if weight > max_weight then 
                max_weight = weight
                ret_card_list = card_list
            end
        end
    end

    if #ret_card_list > 0 then
        dbglog("出大牌",ret_card_list)
        return ret_card_list
    end

    max_weight = 0
    for card_type,type_list in pairs(max_big_card_list) do
        for _,card_list in pairs(type_list) do
            local weight = 0 - get_card_logic_value(card_list[1])
            if weight > max_weight then 
                max_weight = weight
                ret_card_list = card_list
            end
        end
    end

    if #ret_card_list > 0 then
        dbglog("出绝对大牌",ret_card_list)
        return ret_card_list
    end

    --都没有找到出最小牌
    ret_card_list = get_min_hander(self_card_type_list,alert_list,didui_card_count)
    if #ret_card_list > 0 then
        dbglog("都没有找到出最小牌",ret_card_list)
        return ret_card_list
    end
    return get_min_card(self)
end

--地主后手出牌
function dizhu_last_play(self,last_record)
    local didui_card_type_list = {shangjia_card_type_list,xiajia_card_type_list}
    local didui_card_id_list = {shangjia_card_id_list,xiajia_card_id_list}
    dbglog("dizhu_last_play",self_card_type_list,last_record)
        --农民爆单牌型
    local alert_list = check_alert_list(didui_card_type_list)
    --绝对大牌 大牌 小牌
    local max_big_card_list,big_card_list,small_card_list,max_big_handle_count,big_handle_count,small_handle_count = analyse_card_type_list(self_card_type_list,didui_card_type_list,didui_card_id_list)

    --剩下一手小牌 
    if big_handle_count + small_handle_count == 1 then
        dbglog("剩下一手小牌")
        if #alert_list == 0 and self_card_handle_count > 2 then
            for _,card_list in pairs(small_card_list[last_record.card_suit_type] or {}) do
                if self.ddz_instance:compare_card_list(last_record,card_list) then
                    return card_list
                end
            end  
        end

        for _,card_list in pairs(max_big_card_list[last_record.card_suit_type] or {}) do
            if self.ddz_instance:compare_card_list(last_record,card_list) then
                return card_list
            end
        end  

        if max_big_card_list[CARD_SUIT_TYPE_ZHADAN] and last_record.card_suit_type ~= CARD_SUIT_TYPE_ZHADAN then
            return max_big_card_list[CARD_SUIT_TYPE_ZHADAN][1]
        end

        if max_big_card_list[CARD_SUIT_TYPE_WANGZHA] then
            return max_big_card_list[CARD_SUIT_TYPE_WANGZHA][1]
        end
    end

    --从分析好的手牌中找一副同牌型的牌压
    for _,card_list in pairs(self_card_type_list[last_record.card_suit_type]) do
        if last_record.card_suit_type == CARD_SUIT_TYPE_ZHADAN then break end
        if self.ddz_instance:compare_card_list(last_record,card_list) then
            if last_record.card_suit_type ==CARD_SUIT_TYPE_DANPAI and get_card_logic_value(card_list[1]) > 14 then
                goto continue
            end
            if not alert_list[last_record.card_suit_type] then
                return card_list
            elseif alert_list[last_record.card_suit_type] and #alert_list[last_record.card_suit_type][1] == #card_list and self.ddz_instance:compare_card_list(last_record,card_list) then
                return card_list
            end
            ::continue::
        end
    end

    --考虑是否拆手牌
    local ret_card_list = force_out_card(self,self_card_type_list,last_record,alert_list)

    if ret_card_list then
        return ret_card_list
    end

    --大牌数量大于小牌数量 可以用炸弹
    if (max_big_handle_count + big_handle_count > small_handle_count or max_big_handle_count >= big_handle_count + small_handle_count ) and big_handle_count + small_handle_count < shangjia_card_handle_count  and big_handle_count + small_handle_count <= xiajia_card_handle_count and (shangjia_card_handle_count <= 3 or xiajia_card_handle_count <= 3) then
        for _,card_list in pairs(self_card_type_list[CARD_SUIT_TYPE_ZHADAN]) do
            if self.ddz_instance:compare_card_list(last_record,card_list) then
                return card_list
            end
        end
        if #self_card_type_list[CARD_SUIT_TYPE_WANGZHA] > 0 then
            return self_card_type_list[CARD_SUIT_TYPE_WANGZHA][1]
        end  
    elseif last_record.card_suit_type == CARD_SUIT_TYPE_DANPAI and #self_card_type_list[CARD_SUIT_TYPE_WANGZHA] > 0 then
        return {BLACK_JOKER_NUMBER}
    end

    --强行拆牌 压单压对子
    if self_card_handle_count <= 2 or shangjia_card_handle_count <=2 or xiajia_card_handle_count <=2 then
        ret_card_list = force_out_dan_dui(self,last_record,alert_list)
        if ret_card_list then
            return ret_card_list
        end
    end
    return {}
end

--地主下家先手出牌
function xiajia_first_play(self)
    local didui_card_type_list = {shangjia_card_type_list}
    local didui_card_id_list = {shangjia_card_id_list}
    local didui_card_count = {#shangjia_card_id_list}
    dbglog(self_card_handle_count)
    --最后一手牌 打掉
    if self_card_handle_count == 1 then
        return get_min_hander(self_card_type_list,nil,didui_card_count)
    end

    --绝对大牌 大牌 小牌
    local max_big_card_list,big_card_list,small_card_list,max_big_handle_count,big_handle_count,small_handle_count = analyse_card_type_list(self_card_type_list,didui_card_type_list,didui_card_id_list)

    --只有一手 大牌 小牌 出绝对大牌 
    if big_handle_count + small_handle_count == 1 then
        return get_min_hander(max_big_card_list,nil,didui_card_count)
    end

    --队友爆单牌型
    local friend_alert_list = check_alert_list(didui_card_type_list)
    for card_type,type_list in pairs(friend_alert_list) do
        for _,card_list in pairs(self_card_type_list[card_type]) do
            if get_card_logic_value(card_list[1]) < get_card_logic_value(type_list[1][1]) then
                return card_list
            end
        end
    end

    --地主爆单牌型
    local alert_list = check_alert_list(didui_card_type_list)

    --出非敌方爆单牌型的小牌，优先出 自己大牌里面有相同牌型的 或者友军有此类牌型大牌的，否则出最小牌型牌
    --寻找合适的小牌
    local ret_card_list = {}
    local max_weight = -100
    for card_type,type_list in pairs(small_card_list) do
        for _,card_list in pairs(type_list) do
            if card_type == CARD_SUIT_TYPE_ZHADAN  then
                break
            end
            local key = true
            --排除报单牌型
            for alert_card_type,alert_card_list in pairs(alert_list) do
                if #alert_card_list[1] == #card_list and alert_card_type == card_type and get_card_logic_value(alert_card_list[1][1]) > get_card_logic_value(card_list[1]) then
                    key = false
                end
            end
            if key then
                local weight = 0 - get_card_logic_value(card_list[1])
                weight = weight + #card_list
                --自己有大牌可以接回来
                if max_big_card_list[card_type] and #max_big_card_list[card_type] > 0 and get_card_logic_value(card_list[1]) < 10  then
                    weight = weight + 100
                end

                --队友有大牌可以接回来
                local youjun_type_list = xiajia_card_type_list[card_type]
                if #youjun_type_list > 0 and get_card_logic_value(youjun_type_list[#youjun_type_list][1]) > get_card_logic_value(card_list[1]) then
                    weight = weight + 100
                end

                if get_card_logic_value(card_list[1]) >= 14 then
                    weight = weight - 100
                end

                weight = weight + #self_card_type_list[card_type] * 10

                if card_type == CARD_SUIT_TYPE_DANSHUN or card_type == CARD_SUIT_TYPE_SHUANGSHUN  then
                    weight = weight + 50
                end 

                if big_card_list[card_type] and #big_card_list[card_type] > 0 and get_card_logic_value(card_list[1]) < 10 then
                    weight = weight + 100
                end 

                if weight > max_weight then 
                    max_weight = weight
                    ret_card_list = card_list
                end
            end
        end
    end

    --大牌中，值小余 10 的牌
    for card_type,type_list in pairs(big_card_list) do
        for _,card_list in pairs(type_list) do
            if card_type == CARD_SUIT_TYPE_WANGZHA or card_type == CARD_SUIT_TYPE_ZHADAN  then
                break
            end
           local weight = 0 - get_card_logic_value(card_list[1]) 
           weight = weight + #card_list
           if (card_type == CARD_SUIT_TYPE_FEIJI or card_type == CARD_SUIT_TYPE_FEIJIDAICIBANG) and self_card_handle_count <= 3 then
                weight = weight + 200
            end
           if get_card_logic_value(card_list[1]) < 8 then
                weight = weight + 150
           end
          if weight > max_weight then 
                max_weight = weight
                ret_card_list = card_list
            end
        end
    end

    for card_type,type_list in pairs(max_big_card_list) do
        for _,card_list in pairs(type_list) do
            if card_type == CARD_SUIT_TYPE_WANGZHA or card_type == CARD_SUIT_TYPE_ZHADAN  then
                break
            end
            local weight = 0 - get_card_logic_value(card_list[1]) 
            weight = weight + #card_list
            if (card_type == CARD_SUIT_TYPE_FEIJI or card_type == CARD_SUIT_TYPE_FEIJIDAICIBANG) and self_card_handle_count <= 3 then
                weight = weight + 200
            end
           if get_card_logic_value(card_list[1]) < 7 then
                weight = weight + 150
           end
           if weight > max_weight then 
                max_weight = weight
                ret_card_list = card_list
            end
        end
    end

    for card_type,type_list in pairs(self_card_type_list) do
        for _,card_list in pairs(type_list) do
            local weight = 0 - get_card_logic_value(card_list[1])

            if (card_type == CARD_SUIT_TYPE_DANSHUN and get_card_logic_value(card_list[#card_list]) < 11 ) or (card_type == CARD_SUIT_TYPE_SHUANGSHUN and get_card_logic_value(card_list[#card_list]) < 9) or (card_type == CARD_SUIT_TYPE_FEIJIDAICIBANG and get_card_logic_value(card_list[1]) < 9) then
                weight = weight + 150
            else
                break
            end

            if get_card_logic_value(card_list[1]) >= 13 then
                weight = weight - 100
            end

            if weight > max_weight then 
                max_weight = weight
                ret_card_list = card_list
            end
        end
    end


    if #ret_card_list > 0 then
        return ret_card_list
    end

    --小牌没有找到合适的牌从大牌和绝对大牌中选最小的牌打
    max_weight = 0
    for card_type,type_list in pairs(big_card_list) do
        for _,card_list in pairs(type_list) do
            local weight = 0 - get_card_logic_value(card_list[1])
            if max_big_card_list[card_type] and #max_big_card_list[card_type] > 0 then
                weight = weight + 100
            end

            if weight > max_weight then 
                max_weight = weight
                ret_card_list = card_list
            end
        end
    end

    if #ret_card_list > 0 then
        return ret_card_list
    end

    max_weight = 0
    for card_type,type_list in pairs(max_big_card_list) do
        for _,card_list in pairs(type_list) do
            local weight = 0 - get_card_logic_value(card_list[1])
            if weight > max_weight then 
                max_weight = weight
                ret_card_list = card_list
            end
        end
    end

    if #ret_card_list > 0 then
        return ret_card_list
    end

    --都没有找到出最小牌
    ret_card_list = get_min_hander(self_card_type_list,alert_list,didui_card_count)
    if #ret_card_list > 0 then
        dbglog("都没有找到出最小牌",ret_card_list)
        return ret_card_list
    end
    return get_min_card(self)
end

--地主下家后手出牌
function xiajia_last_play(self,last_record)
    local didui_card_type_list = {shangjia_card_type_list}
    local didui_card_id_list = {shangjia_card_id_list}
    dbglog("xiajia_last_play",self_card_type_list,last_record)
        --地主爆单牌型
    local alert_list = check_alert_list(didui_card_type_list)
    local card = last_record.card_suit[1]
    local card_clv = get_card_logic_value(card)

    --绝对大牌 大牌 小牌
    local max_big_card_list,big_card_list,small_card_list,max_big_handle_count,big_handle_count,small_handle_count = analyse_card_type_list(self_card_type_list,didui_card_type_list,didui_card_id_list)

    --剩下一手小牌 手中有绝对大的王炸和炸弹
    if big_handle_count + small_handle_count == 1 then
        if #alert_list == 0 and self_card_handle_count > 2 then
            for _,card_list in pairs(small_card_list[last_record.card_suit_type] or {}) do
                if self.ddz_instance:compare_card_list(last_record,card_list) then
                    return card_list
                end
            end  
        end
        for _,card_list in pairs(max_big_card_list[last_record.card_suit_type] or {}) do
            if self.ddz_instance:compare_card_list(last_record,card_list) then
                return card_list
            end
        end

        if max_big_card_list[CARD_SUIT_TYPE_ZHADAN] and last_record.card_suit_type ~= CARD_SUIT_TYPE_ZHADAN then
            if self.ddz_instance:compare_card_list(last_record,max_big_card_list[CARD_SUIT_TYPE_ZHADAN][1]) then
                return max_big_card_list[CARD_SUIT_TYPE_ZHADAN][1]
            end
        end

        if max_big_card_list[CARD_SUIT_TYPE_WANGZHA] then
            return max_big_card_list[CARD_SUIT_TYPE_WANGZHA][1]
        end
    end

    --只剩下一手牌
    if (self_card_handle_count == 1 or big_handle_count + small_handle_count == 1) and #self_card_type_list[last_record.card_suit_type] > 0 and self.ddz_instance:compare_card_list(last_record,self_card_type_list[last_record.card_suit_type][1]) then
        return self_card_type_list[last_record.card_suit_type][1]
    end

    --出牌的是队友不强行压
    if last_record.uid == xiajia_uid then
        return {}
    end

    --从分析好的手牌中找一副同牌型的牌压
    for _,card_list in pairs(self_card_type_list[last_record.card_suit_type]) do
        if last_record.card_suit_type == CARD_SUIT_TYPE_ZHADAN then break end
        if self.ddz_instance:compare_card_list(last_record,card_list) then
            if last_record.card_suit_type ==CARD_SUIT_TYPE_DANPAI and get_card_logic_value(card_list[1]) > 14 then
                goto continue
            end
            if not alert_list[last_record.card_suit_type] then
                return card_list
            elseif alert_list[last_record.card_suit_type] and #alert_list[last_record.card_suit_type][1] == #card_list and self.ddz_instance:compare_card_list(last_record,card_list) then
                return card_list
            end
            ::continue::
        end
    end

    --出牌的是队友不强行压
    if last_record.uid == xiajia_uid then
        return {}
    end

    --考虑是否拆手牌
    local ret_card_list = force_out_card(self,self_card_type_list,last_record,alert_list)
    dbglog(ret_card_list)
    if ret_card_list then
        return ret_card_list
    end

    --大牌数量大于小牌数量 可以用炸弹
    if (max_big_handle_count + big_handle_count > small_handle_count or max_big_handle_count >= big_handle_count + small_handle_count) and big_handle_count + small_handle_count < shangjia_card_handle_count and shangjia_card_handle_count <= 3 then
        for _,card_list in pairs(self_card_type_list[CARD_SUIT_TYPE_ZHADAN]) do
            if self.ddz_instance:compare_card_list(last_record,card_list) then
                return card_list
            end
        end
        if #self_card_type_list[CARD_SUIT_TYPE_WANGZHA] > 0 then
            return self_card_type_list[CARD_SUIT_TYPE_WANGZHA][1]
        end       
    elseif last_record.card_suit_type == CARD_SUIT_TYPE_DANPAI and #self_card_type_list[CARD_SUIT_TYPE_WANGZHA] > 0 then
        return {BLACK_JOKER_NUMBER}
    end

    --强行拆牌 压单压对子
    if self_card_handle_count <= 2 or shangjia_card_handle_count <=2 then
        ret_card_list = force_out_dan_dui(self,last_record,alert_list)
        if ret_card_list then
            return ret_card_list
        end
    end
    return {}
end

--地主上家先手出牌
function shangjia_first_play(self)
    local didui_card_type_list = {xiajia_card_type_list}
    local didui_card_id_list = {xiajia_card_id_list}
    local didui_card_count = {#xiajia_card_id_list}
    dbglog(self_card_handle_count)
    --最后一手牌 打掉
    if self_card_handle_count == 1 then
        return get_min_hander(self_card_type_list,nil,didui_card_count)
    end

    --绝对大牌 大牌 小牌
    local max_big_card_list,big_card_list,small_card_list,max_big_handle_count,big_handle_count,small_handle_count = analyse_card_type_list(self_card_type_list,didui_card_type_list,didui_card_id_list)
    dbglog(max_big_card_list,big_card_list,small_card_list,max_big_handle_count,big_handle_count,small_handle_count)
    --只有一手 大牌 小牌 出绝对大牌 
    if big_handle_count + small_handle_count <= 1 then
        return get_min_hander(max_big_card_list,nil,didui_card_count)
    end

    --农民爆单牌型
    local alert_list = check_alert_list(didui_card_type_list)

    --出非敌方爆单牌型的小牌，优先出 自己大牌里面有相同牌型的 或者友军有此类牌型大牌的，否则出最小牌型牌
    --寻找合适的小牌
    local max_weight = -100
    local ret_card_list = {}
    for card_type,type_list in pairs(small_card_list) do
        for _,card_list in pairs(type_list) do
            if card_type == CARD_SUIT_TYPE_ZHADAN then
                break
            end
            local key = true
            --排除报单牌型
            for alert_card_type,alert_card_list in pairs(alert_list) do
                if #alert_card_list[1] == #card_list and alert_card_type == card_type and get_card_logic_value(alert_card_list[1][1]) > get_card_logic_value(card_list[1]) then
                    key = false
                end
            end
            if key then
                local weight = 0 - get_card_logic_value(card_list[1])
                weight = weight + #card_list
                --自己有大牌可以接回来
                if max_big_card_list[card_type] and #max_big_card_list[card_type] > 0 and get_card_logic_value(card_list[1]) < 10  then
                    weight = weight + 100
                end
                weight = weight + #self_card_type_list[card_type] * 10

                --队友有大牌可以接回来
                local youjun_type_list = shangjia_card_type_list[card_type]
                if #youjun_type_list > 0 and get_card_logic_value(youjun_type_list[#youjun_type_list][1]) > get_card_logic_value(card_list[1]) then
                    weight = weight + 100
                end

                if big_card_list[card_type] and #big_card_list[card_type] > 0 and get_card_logic_value(card_list[1]) < 10 then
                    weight = weight + 100
                end 

                if card_type == CARD_SUIT_TYPE_DANSHUN or card_type == CARD_SUIT_TYPE_SHUANGSHUN  then
                    weight = weight + 50
                end 

                if get_card_logic_value(card_list[1]) >= 14 then
                    weight = weight - 100
                end

                if weight > max_weight then 
                    max_weight = weight
                    ret_card_list = card_list
                end
            end
        end
    end

    --大牌中，值小余 10 的牌
    for card_type,type_list in pairs(big_card_list) do
        for _,card_list in pairs(type_list) do
            if card_type == CARD_SUIT_TYPE_WANGZHA or card_type == CARD_SUIT_TYPE_ZHADAN  then
                break
            end
            local weight = 0 - get_card_logic_value(card_list[1]) 
            weight = weight + #card_list
            if (card_type == CARD_SUIT_TYPE_FEIJI or card_type == CARD_SUIT_TYPE_FEIJIDAICIBANG) and self_card_handle_count <= 3 then
                weight = weight + 200
            end
           if get_card_logic_value(card_list[1]) < 8 then
                weight = weight + 150
           end
          if weight > max_weight then 
                max_weight = weight
                ret_card_list = card_list
            end
        end
    end

    for card_type,type_list in pairs(max_big_card_list) do
        for _,card_list in pairs(type_list) do
            if card_type == CARD_SUIT_TYPE_WANGZHA or card_type == CARD_SUIT_TYPE_ZHADAN  then
                break
            end
            local weight = 0 - get_card_logic_value(card_list[1]) 
            weight = weight + #card_list
            if (card_type == CARD_SUIT_TYPE_FEIJI or card_type == CARD_SUIT_TYPE_FEIJIDAICIBANG) and self_card_handle_count <= 3 then
                weight = weight + 200
            end
           if get_card_logic_value(card_list[1]) < 7 then
                weight = weight + 150
           end
           if weight > max_weight then 
                max_weight = weight
                ret_card_list = card_list
            end
        end
    end

    for card_type,type_list in pairs(self_card_type_list) do
        for _,card_list in pairs(type_list) do
            local weight = 0 - get_card_logic_value(card_list[1])
            if (card_type == CARD_SUIT_TYPE_DANSHUN and get_card_logic_value(card_list[#card_list]) < 11 ) or (card_type == CARD_SUIT_TYPE_SHUANGSHUN and get_card_logic_value(card_list[#card_list]) < 9) or (card_type == CARD_SUIT_TYPE_FEIJIDAICIBANG and get_card_logic_value(card_list[1]) < 9) then
                weight = weight + 150
            else
                break
            end

            if get_card_logic_value(card_list[1]) >= 13 then
                weight = weight - 100
            end

            if weight > max_weight then 
                max_weight = weight
                ret_card_list = card_list
            end
        end
    end


    if #ret_card_list > 0 then
        return ret_card_list
    end

    --小牌没有找到合适的牌从大牌和绝对大牌中选最小的牌打
    max_weight = 0
    for card_type,type_list in pairs(big_card_list) do
        for _,card_list in pairs(type_list) do
            local weight = 0 - get_card_logic_value(card_list[1])
            if max_big_card_list[card_type] and #max_big_card_list[card_type] > 0 then
                weight = weight + 100
            end

            if weight > max_weight then 
                max_weight = weight
                ret_card_list = card_list
            end
        end
    end

    if #ret_card_list > 0 then
        return ret_card_list
    end

    max_weight = 0
    for card_type,type_list in pairs(max_big_card_list) do
        for _,card_list in pairs(type_list) do
            local weight = 0 - get_card_logic_value(card_list[1])
            if weight > max_weight then 
                max_weight = weight
                ret_card_list = card_list
            end
        end
    end

    if #ret_card_list > 0 then
        return ret_card_list
    end

    --都没有找到出最小牌
    ret_card_list = get_min_hander(self_card_type_list,alert_list,didui_card_count)
    if #ret_card_list > 0 then
        dbglog("都没有找到出最小牌",ret_card_list)
        return ret_card_list
    end
    return get_min_card(self)
end

--地主上家后手出牌
function shangjia_last_play(self,last_record)
    local didui_card_type_list = {xiajia_card_type_list}
    local didui_card_id_list = {xiajia_card_id_list}
    dbglog("shangjia_last_play",self_card_type_list,last_record)
        --爆单牌型
    local alert_list = check_alert_list(didui_card_type_list)
    local card = last_record.card_suit[1]
    local card_clv = get_card_logic_value(card)


    --绝对大牌 大牌 小牌
    local max_big_card_list,big_card_list,small_card_list,max_big_handle_count,big_handle_count,small_handle_count = analyse_card_type_list(self_card_type_list,didui_card_type_list,didui_card_id_list)

        --只剩下一手牌
    if (self_card_handle_count == 1 or big_handle_count + small_handle_count == 1) and #self_card_type_list[last_record.card_suit_type] > 0 and
    self.ddz_instance:compare_card_list(last_record,self_card_type_list[last_record.card_suit_type][1]) then
        return self_card_type_list[last_record.card_suit_type][1]
    end


    --剩下一手小牌
    if big_handle_count + small_handle_count == 1 then
        if #alert_list == 0 and self_card_handle_count > 2 then
            for _,card_list in pairs(small_card_list[last_record.card_suit_type] or {}) do
                if self.ddz_instance:compare_card_list(last_record,card_list) then
                    return card_list
                end
            end  
        end
        for _,card_list in pairs(max_big_card_list[last_record.card_suit_type] or {}) do
            if self.ddz_instance:compare_card_list(last_record,card_list) then
                return card_list
            end
        end

        if max_big_card_list[CARD_SUIT_TYPE_ZHADAN] and last_record.card_suit_type ~= CARD_SUIT_TYPE_ZHADAN then
            if self.ddz_instance:compare_card_list(last_record,max_big_card_list[CARD_SUIT_TYPE_ZHADAN][1]) then
                return max_big_card_list[CARD_SUIT_TYPE_ZHADAN][1]
            end
        end
        if max_big_card_list[CARD_SUIT_TYPE_WANGZHA] then
            return max_big_card_list[CARD_SUIT_TYPE_WANGZHA][1]
        end
    end

    dbglog(last_record.uid,shangjia_uid,last_record.card_suit_type,card_clv)
    --是队友炸弹 牌大于A不强行压
    if last_record.uid == shangjia_uid and (last_record.card_suit_type == CARD_SUIT_TYPE_ZHADAN or card_clv >= 12 ) then
        return {}
    end

    --队友能出完不压
    if last_record.uid == shangjia_uid then
        local _,_,_,max_count,big_count,small_count = analyse_card_type_list(shangjia_card_type_list,didui_card_type_list,didui_card_id_list)
        if big_count + small_count <= 1 or shangjia_card_handle_count == 1 then
            return {}
        end
    end

    --从分析好的手牌中找一副同牌型的牌压
    for _,card_list in pairs(self_card_type_list[last_record.card_suit_type]) do
        if last_record.card_suit_type == CARD_SUIT_TYPE_ZHADAN then break end
        if self.ddz_instance:compare_card_list(last_record,card_list) then
            if last_record.card_suit_type ==CARD_SUIT_TYPE_DANPAI and get_card_logic_value(card_list[1]) > 14 then
                goto continue
            end
            if not alert_list[last_record.card_suit_type] then
                return card_list
            elseif alert_list[last_record.card_suit_type] and #alert_list[last_record.card_suit_type][1] == #card_list and self.ddz_instance:compare_card_list(last_record,card_list) then
                return card_list
            end
            ::continue::
        end
    end

    --考虑是否拆手牌
    local ret_card_list = force_out_card(self,self_card_type_list,last_record,alert_list)

    if ret_card_list then
        return ret_card_list
    end

    --出牌的是队友不强行压
    if last_record.uid == shangjia_uid then
        return {}
    end

    --大牌数量大于小牌数量 可以用炸弹
    if (max_big_handle_count + big_handle_count > small_handle_count or max_big_handle_count >= big_handle_count + small_handle_count)  and big_handle_count + small_handle_count < xiajia_card_handle_count and xiajia_card_handle_count <= 3 then
        for _,card_list in pairs(self_card_type_list[CARD_SUIT_TYPE_ZHADAN]) do
            if self.ddz_instance:compare_card_list(last_record,card_list) then
                return card_list
            end
        end
        if #self_card_type_list[CARD_SUIT_TYPE_WANGZHA] > 0 then
            return self_card_type_list[CARD_SUIT_TYPE_WANGZHA][1]
        end    
    elseif last_record.card_suit_type == CARD_SUIT_TYPE_DANPAI and #self_card_type_list[CARD_SUIT_TYPE_WANGZHA] > 0 then
        return {BLACK_JOKER_NUMBER}
    end
    --强行拆牌 压单压对子
    if self_card_handle_count <= 2 or xiajia_card_handle_count <= 2 then
        ret_card_list = force_out_dan_dui(self,last_record,alert_list)
        if ret_card_list then
            return ret_card_list
        end
    end
    return {}
end

function M.analyse_jiabei(self)
    xiajia_uid = self.ddz_instance:get_next_position_uid(self.uid)
    shangjia_uid = self.ddz_instance:get_next_position_uid(xiajia_uid)
    --确定牌型
    self_card_type_list,self_card_handle_count,self_card_id_list = assert(make_card_type(self.uid,self.ddz_instance)) 
    shangjia_card_type_list,shangjia_card_handle_count,shangjia_card_id_list  = assert(make_card_type(shangjia_uid,self.ddz_instance))        --上家的手牌  分析过后的牌组
    xiajia_card_type_list,xiajia_card_handle_count,xiajia_card_id_list   = assert(make_card_type(xiajia_uid,self.ddz_instance))         --下家的手牌  
    dbglog(self_card_type_list,shangjia_card_type_list,xiajia_card_type_list)
    local didui_card_type_list = {shangjia_card_type_list,xiajia_card_type_list}
    local didui_card_id_list = {shangjia_card_id_list,xiajia_card_id_list}

    --绝对大牌 大牌 小牌
    local max_big_card_list,big_card_list,small_card_list,max_big_handle_count,big_handle_count,small_handle_count = analyse_card_type_list(self_card_type_list,didui_card_type_list,didui_card_id_list)
    local is_jiabei = false
    if max_big_handle_count + big_handle_count > small_handle_count then
        is_jiabei = true
    end
    return { type = is_jiabei and 1 or 0}
end

function M.analyse_play(self)
    local ddz_instance = assert(self.ddz_instance)
    local last_record = ddz_instance:get_last_card_suit_ex()
    dbglog(last_record)
    local must_play = false
    if not last_record or last_record.uid == self.uid then
        must_play = true
    end

    local role = ddz_instance:get_role(self.uid)
    xiajia_uid = self.ddz_instance:get_next_position_uid(self.uid)
    shangjia_uid = self.ddz_instance:get_next_position_uid(xiajia_uid)
    --确定牌型
    self_card_type_list,self_card_handle_count,self_card_id_list = assert(make_card_type(self.uid,ddz_instance)) 
    shangjia_card_type_list,shangjia_card_handle_count,shangjia_card_id_list  = assert(make_card_type(shangjia_uid,ddz_instance))        --上家的手牌  分析过后的牌组
    xiajia_card_type_list,shangjia_card_handle_count,xiajia_card_id_list   = assert(make_card_type(xiajia_uid,ddz_instance))         --下家的手牌  分析过后的牌组
    dbglog(self_card_type_list)
    dbglog(shangjia_card_type_list)
    dbglog(xiajia_card_type_list)
    local result_card_id_list
    --先手
    if must_play then
        if role == 0 then --地主先手出牌
            result_card_id_list = dizhu_first_play(self)
        elseif role == 1 then
            result_card_id_list = xiajia_first_play(self)
        elseif role == 2 then
            result_card_id_list = shangjia_first_play(self)
        end
    else --后手
        if role == 0 then --地主后手出牌
            result_card_id_list = dizhu_last_play(self,last_record)
        elseif role == 1 then
            result_card_id_list = xiajia_last_play(self,last_record)
        elseif role == 2 then
            result_card_id_list = shangjia_last_play(self,last_record)
        end
        dbglog(last_record)
    end
    dbglog(self.uid,result_card_id_list)
    return {card_suit = result_card_id_list}
end

function M.analyse_rob_dizhu(self)
    local ddz_instance = assert(self.ddz_instance)
    -- if not self.is_rob then
    --     self.is_rob = is_need_rob_dizhu(self)
    -- end
    local dipai = self.ddz_instance:get_dipai_card_list()

    xiajia_uid = self.ddz_instance:get_next_position_uid(self.uid)
    shangjia_uid = self.ddz_instance:get_next_position_uid(xiajia_uid)
    --确定牌型
    self_card_type_list,self_card_handle_count,self_card_id_list,wang_er = assert(make_card_type(self.uid,self.ddz_instance,dipai)) 
    shangjia_card_type_list,shangjia_card_handle_count,shangjia_card_id_list  = assert(make_card_type(shangjia_uid,self.ddz_instance))        --上家的手牌  分析过后的牌组
    xiajia_card_type_list,xiajia_card_handle_count,xiajia_card_id_list   = assert(make_card_type(xiajia_uid,self.ddz_instance))         --下家的手牌  
    dbglog(self_card_type_list,shangjia_card_type_list,xiajia_card_type_list)
    local didui_card_type_list = {shangjia_card_type_list,xiajia_card_type_list}
    local didui_card_id_list = {shangjia_card_id_list,xiajia_card_id_list}

    --绝对大牌 大牌 小牌
    local max_big_card_list,big_card_list,small_card_list,max_big_handle_count,big_handle_count,small_handle_count = analyse_card_type_list(self_card_type_list,didui_card_type_list,didui_card_id_list)
    dbglog(self.uid,"max:",max_big_handle_count," big:",big_handle_count," small:",small_handle_count)
    local score = 0
    if max_big_handle_count > 0 and max_big_handle_count + big_handle_count >= small_handle_count then
        score = 3
    elseif self_card_handle_count <= 9 and max_big_handle_count + big_handle_count >= small_handle_count - 2 then
        if wang_er > 4 then
            score = 2
        elseif wang_er >= 2 then
            score = 1
        end
    end

    return {score = score,is_rob = score > 0 and 1 or 0}
end


return M
